mirror of
https://github.com/kerberos-io/helm-charts.git
synced 2026-10-28 19:08:26 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f1dcf8f00 | ||
|
|
371408e5eb |
@@ -16,7 +16,7 @@ type: application
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 0.167.2
|
||||
version: 0.167.3
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
|
||||
+25
-8
@@ -73,15 +73,16 @@ the primary and demo frontends, which share the frontend image tag. Update the
|
||||
live Argo CD Application's chart pin as well as its values: an image-only
|
||||
upgrade leaves older charts forwarding to port `80` and causes gateway errors.
|
||||
|
||||
### Hardened Admin image (opt-in, unreleased chart support)
|
||||
### Hardened Admin image (opt-in, chart 0.167.3)
|
||||
|
||||
`charts/hub` deploys Admin in `all` and `ui` modes. The shell-free image proposed
|
||||
by `uug-ai/admin#59` runs as `65532:65532` and listens on `8080`, unlike the legacy
|
||||
image on `80`. When selecting a verified compatible image, set these values
|
||||
together; the chart does not select or upgrade that image automatically:
|
||||
`charts/hub` deploys Admin in `all` and `ui` modes. Shell-free Admin `v1.4.3`
|
||||
runs as `65532:65532` and listens on `8080`, unlike the legacy image on `80`.
|
||||
Set these values together; the chart does not upgrade the image automatically:
|
||||
|
||||
```yaml
|
||||
admin:
|
||||
repository: ghcr.io/uug-ai/admin
|
||||
tag: v1.4.3
|
||||
containerPort: 8080
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
@@ -101,17 +102,33 @@ admin:
|
||||
volumeMounts:
|
||||
- name: admin-tmp
|
||||
mountPath: /tmp
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
```
|
||||
|
||||
Merge the scratch volume with any existing mounts. Only `/tmp` is writable;
|
||||
application files remain read-only. Memory-backed scratch counts against the
|
||||
pod memory limit. The `admin-svc` Service and Admin ingress still use port `80`;
|
||||
only the Service target and container port change. OAuth2-proxy is unchanged.
|
||||
Defaults remain port `80` with no security context or added volumes. Coordinate
|
||||
the Service targets the named `http` container port. OAuth2-proxy is unchanged.
|
||||
Defaults remain port `80` with no security context, added volumes, or probes. Coordinate
|
||||
the image, values and a chart revision containing these settings: published
|
||||
`0.167.2` does not contain Admin runtime support.
|
||||
|
||||
### Hardened Hub workers (opt-in, unreleased chart support)
|
||||
Rollbacks to legacy images must restore port `80`, remove the hardened
|
||||
security context, and disable `/healthz` probes together. Run
|
||||
`bash scripts/check-admin-runtime.sh` from the repository root to verify
|
||||
legacy defaults, hardened runtime/probes, and unchanged OAuth2 routing.
|
||||
|
||||
### Hardened Hub workers (opt-in, chart 0.167.3)
|
||||
|
||||
The worker templates accept **per-component** `securityContext` (container) and
|
||||
`podSecurityContext` (pod) maps. Both default to `{}` and are omitted from the
|
||||
|
||||
@@ -40,8 +40,16 @@ spec:
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.admin.containerPort }}
|
||||
containerPort: {{ .Values.admin.containerPort | default 80 }}
|
||||
protocol: TCP
|
||||
{{- with .Values.admin.readinessProbe }}
|
||||
readinessProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.admin.livenessProbe }}
|
||||
livenessProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
env:
|
||||
- name: LOG_LEVEL
|
||||
value: "{{ .Values.admin.logLevel }}"
|
||||
|
||||
@@ -10,7 +10,7 @@ spec:
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: {{ .Values.admin.containerPort }}
|
||||
targetPort: http
|
||||
name: http
|
||||
selector:
|
||||
app: admin
|
||||
|
||||
@@ -271,6 +271,8 @@ admin:
|
||||
# Opt in to 8080 and a securityContext only with a compatible hardened image.
|
||||
containerPort: 80
|
||||
securityContext: {}
|
||||
readinessProbe: {}
|
||||
livenessProbe: {}
|
||||
pullPolicy: IfNotPresent
|
||||
tag: "v1.3.0"
|
||||
replicas: 2
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
CHART_DIR="${1:-charts/hub}"
|
||||
|
||||
resource() {
|
||||
local source="$1"
|
||||
awk -v source="# Source: hub/templates/admin/$source.yaml" '
|
||||
/^---/ { selected=0 }
|
||||
/^# Source:/ { selected=($0 == source); next }
|
||||
selected { print }
|
||||
'
|
||||
}
|
||||
|
||||
assert_contains() {
|
||||
local rendered="$1" pattern="$2"
|
||||
if ! grep -Eq -- "$pattern" <<< "$rendered"; then
|
||||
printf 'Missing expected Admin setting: %s\n' "$pattern" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_absent() {
|
||||
local rendered="$1" pattern="$2"
|
||||
if grep -Eq -- "$pattern" <<< "$rendered"; then
|
||||
printf 'Unexpected Admin setting: %s\n' "$pattern" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
HARDENED_FLAGS=(
|
||||
--set admin.containerPort=8080
|
||||
--set-json 'admin.securityContext={"runAsNonRoot":true,"runAsUser":65532,"runAsGroup":65532,"readOnlyRootFilesystem":true,"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"seccompProfile":{"type":"RuntimeDefault"}}'
|
||||
--set-json 'admin.volumes=[{"name":"admin-tmp","emptyDir":{"medium":"Memory","sizeLimit":"16Mi"}}]'
|
||||
--set-json 'admin.volumeMounts=[{"name":"admin-tmp","mountPath":"/tmp"}]'
|
||||
--set-json 'admin.readinessProbe={"httpGet":{"path":"/healthz","port":"http"},"periodSeconds":10}'
|
||||
--set-json 'admin.livenessProbe={"httpGet":{"path":"/healthz","port":"http"},"initialDelaySeconds":10,"periodSeconds":10}'
|
||||
)
|
||||
|
||||
for mode in all ui; do
|
||||
default_render="$(helm template hub "$CHART_DIR" --set "mode=$mode" --set admin.oauth2Proxy.enabled=true)"
|
||||
default_deployment="$(resource deployment <<< "$default_render")"
|
||||
default_service="$(resource service <<< "$default_render")"
|
||||
default_ingress="$(resource ingress <<< "$default_render")"
|
||||
default_oauth="$(resource oauth2-proxy <<< "$default_render")"
|
||||
assert_contains "$default_deployment" 'containerPort: 80$'
|
||||
assert_absent "$default_deployment" 'securityContext:|readinessProbe:|livenessProbe:'
|
||||
assert_contains "$default_service" 'port: 80$'
|
||||
assert_contains "$default_service" 'targetPort: http$'
|
||||
|
||||
hardened_render="$(helm template hub "$CHART_DIR" --set "mode=$mode" --set admin.oauth2Proxy.enabled=true "${HARDENED_FLAGS[@]}")"
|
||||
hardened_deployment="$(resource deployment <<< "$hardened_render")"
|
||||
assert_contains "$hardened_deployment" 'containerPort: 8080$'
|
||||
assert_absent "$hardened_deployment" 'containerPort: 80$'
|
||||
for setting in 'runAsNonRoot: true' 'runAsUser: 65532' 'runAsGroup: 65532' \
|
||||
'readOnlyRootFilesystem: true' 'allowPrivilegeEscalation: false' \
|
||||
'type: RuntimeDefault' 'drop:' '- ALL' 'medium: Memory' \
|
||||
'sizeLimit: 16Mi' 'mountPath: /tmp' 'name: admin-tmp'; do
|
||||
assert_contains "$hardened_deployment" "^[[:space:]]*(- )?$setting$"
|
||||
done
|
||||
for probe in readinessProbe livenessProbe; do
|
||||
probe_render="$(awk -v probe="$probe:" '
|
||||
/^ [a-zA-Z]/ { selected=($1 == probe) }
|
||||
selected { print }
|
||||
' <<< "$hardened_deployment")"
|
||||
assert_contains "$probe_render" 'path: /healthz$'
|
||||
assert_contains "$probe_render" 'port: http$'
|
||||
done
|
||||
|
||||
[[ "$(resource service <<< "$hardened_render")" == "$default_service" ]]
|
||||
[[ "$(resource ingress <<< "$hardened_render")" == "$default_ingress" ]]
|
||||
[[ "$(resource oauth2-proxy <<< "$hardened_render")" == "$default_oauth" ]]
|
||||
assert_contains "$default_ingress" 'nginx.ingress.kubernetes.io/auth-url:'
|
||||
assert_contains "$default_ingress" 'number: 80$'
|
||||
|
||||
echo "OK ($mode): legacy defaults; hardened runtime/probes; stable Service, ingress and OAuth2"
|
||||
done
|
||||
|
||||
pipeline_render="$(helm template hub "$CHART_DIR" --set mode=pipeline "${HARDENED_FLAGS[@]}")"
|
||||
assert_absent "$pipeline_render" '^# Source: hub/templates/admin/'
|
||||
|
||||
echo "All Admin runtime checks passed."
|
||||
@@ -171,9 +171,9 @@ for mode in all ui pipeline; do
|
||||
done
|
||||
old_service="$(resource Service admin-svc <<< "$legacy")"
|
||||
service="$(resource Service admin-svc <<< "$configured")"
|
||||
assert_line "$old_service" '^[ ]+targetPort: 80$'
|
||||
assert_line "$old_service" '^[ ]+targetPort: http$'
|
||||
assert_line "$service" '^[ ]+port: 80$'
|
||||
assert_line "$service" '^[ ]+targetPort: 8080$'
|
||||
assert_line "$service" '^[ ]+targetPort: http$'
|
||||
[[ "$(resource Ingress admin-ingress <<< "$legacy")" == "$(resource Ingress admin-ingress <<< "$configured")" ]]
|
||||
[[ "$(resource Deployment oauth2-proxy-admin <<< "$legacy")" == "$(resource Deployment oauth2-proxy-admin <<< "$configured")" ]]
|
||||
[[ "$(resource Service oauth2-proxy-admin <<< "$legacy")" == "$(resource Service oauth2-proxy-admin <<< "$configured")" ]]
|
||||
|
||||
Reference in New Issue
Block a user