-
Notifications
You must be signed in to change notification settings - Fork 1
helm: validate values with a schema, render-time guards, and helm tests #26
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
Open
David Larsen (dc-larsen)
wants to merge
1
commit into
main
Choose a base branch
from
helm-values-validation
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| {{- $fullname := include "socket-firewall.fullname" . -}} | ||
| {{- $apiUrl := (.Values.socket).apiUrl | default "https://api.socket.dev" -}} | ||
| {{- $healthPath := (.Values.healthCheck).path | default "/health" -}} | ||
| {{- $pathRouting := .Values.pathRouting | default dict -}} | ||
| apiVersion: v1 | ||
| kind: Pod | ||
| metadata: | ||
| name: {{ $fullname }}-test-connection | ||
| labels: | ||
| {{- include "socket-firewall.labels" . | nindent 4 }} | ||
| annotations: | ||
| helm.sh/hook: test | ||
| helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded | ||
| spec: | ||
| restartPolicy: Never | ||
| containers: | ||
| - name: test-connection | ||
| image: curlimages/curl:8.11.1 | ||
| securityContext: | ||
| allowPrivilegeEscalation: false | ||
| readOnlyRootFilesystem: false | ||
| runAsNonRoot: true | ||
| capabilities: | ||
| drop: | ||
| - ALL | ||
| seccompProfile: | ||
| type: RuntimeDefault | ||
| command: | ||
| - /bin/sh | ||
| - -c | ||
| - | | ||
| set -u | ||
| BASE="http://{{ $fullname }}:{{ ((.Values.service).httpPort) | default 80 }}" | ||
| fail() { | ||
| echo "FAILED: $1" | ||
| exit 1 | ||
| } | ||
|
|
||
| echo "==> [1] Health endpoint: GET ${BASE}{{ $healthPath }}" | ||
| code=$(curl -s --max-time 15 -o /tmp/health.out -w '%{http_code}' "${BASE}{{ $healthPath }}") || true | ||
| [ "$code" = "200" ] || fail "health check returned HTTP ${code} (expected 200). The firewall Service or pods are not serving traffic." | ||
| grep -q "Health OK" /tmp/health.out || fail "health check returned 200 but the body does not contain 'Health OK'." | ||
| echo " OK (HTTP 200, body contains 'Health OK')" | ||
|
|
||
| echo "==> [2] Socket API egress: GET {{ $apiUrl }}/v0/quota (expect HTTP 401)" | ||
| code=$(curl -s --max-time 15 -o /dev/null -w '%{http_code}' "{{ $apiUrl }}/v0/quota") || true | ||
| if [ "$code" != "401" ]; then | ||
| echo " Hint: HTTP 000 or a timeout means the cluster cannot reach the Socket API" | ||
| echo " (egress blocked, DNS failure, or TLS interception). The firewall needs" | ||
| echo " outbound HTTPS to {{ $apiUrl }} to fetch package verdicts." | ||
| fail "Socket API returned HTTP ${code} (expected exactly 401 — an unauthenticated 401 proves egress and TLS work)." | ||
| fi | ||
| echo " OK (HTTP 401 — egress and TLS to the Socket API verified)" | ||
| {{- if and (eq (include "socket-firewall.metricsExposed" .) "true") ((.Values.redis).enabled) }} | ||
|
|
||
| echo "==> [3] Redis connectivity: GET http://{{ $fullname }}:{{ ((.Values.metrics).port) | default 9145 }}/metrics (expect redis_available 1)" | ||
| curl -s --max-time 15 -o /tmp/metrics.out "http://{{ $fullname }}:{{ ((.Values.metrics).port) | default 9145 }}/metrics" || fail "could not fetch /metrics from the firewall." | ||
| if ! grep -q '^redis_available 1' /tmp/metrics.out; then | ||
| echo " Hint: redis_available 0 means the firewall cannot reach Redis —" | ||
| echo " check the endpoint, TLS settings (redis.ssl / CA cert), and auth" | ||
| echo " (redis.password / redis.existingSecret)." | ||
| fail "metrics do not report 'redis_available 1'." | ||
| fi | ||
| echo " OK (redis_available 1)" | ||
| {{- end }} | ||
| {{- if and $pathRouting.enabled $pathRouting.routes }} | ||
| {{- $firstRoute := first $pathRouting.routes }} | ||
|
|
||
| echo "==> [4] Path routing: GET ${BASE}{{ $firstRoute.path }}/ with Host: {{ $pathRouting.domain }} (expect anything but 404)" | ||
| code=$(curl -s --max-time 15 -o /dev/null -w '%{http_code}' -H "Host: {{ $pathRouting.domain }}" "${BASE}{{ $firstRoute.path }}/") || true | ||
| if [ "$code" = "404" ]; then | ||
| echo " Hint: routing is Host-header based — a 404 means the request did not" | ||
| echo " match pathRouting.domain (or allowedDomain) plus a configured route" | ||
| echo " path. Verify clients send the same Host the firewall is configured for." | ||
| fail "route {{ $firstRoute.path }}/ returned 404 for Host {{ $pathRouting.domain }}." | ||
| fi | ||
| echo " OK (HTTP ${code})" | ||
| {{- end }} | ||
|
|
||
| echo "All checks passed." | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| {{- /* | ||
| Render-time configuration guards. This file renders no manifests — it only | ||
| fails fast on configurations that would deploy but not work. Structural / | ||
| type validation lives in values.schema.json; the checks here are the | ||
| cross-field rules a schema can't express. | ||
|
|
||
| Note: `fail` is a no-op under `helm lint` (lint mode); these guards enforce | ||
| on `helm install`, `helm upgrade`, and `helm template`. | ||
| */ -}} | ||
|
|
||
| {{- $socket := .Values.socket | default dict -}} | ||
| {{- $redis := .Values.redis | default dict -}} | ||
| {{- $pathRouting := .Values.pathRouting | default dict -}} | ||
|
|
||
| {{- /* Path routing enabled with no route source: the firewall starts fine but | ||
| has nothing to match, so every request 404s. Routes can come from the | ||
| inline list, a routes CSV file, or private-registry auto-discovery. */ -}} | ||
| {{- if $pathRouting.enabled -}} | ||
| {{- $hasRoutes := not (empty $pathRouting.routes) -}} | ||
| {{- $hasRoutesFile := not (empty $pathRouting.routesFile) -}} | ||
| {{- $hasAutoDiscovery := and $pathRouting.privateRegistry (($pathRouting.privateRegistry).enabled) -}} | ||
| {{- if not (or $hasRoutes $hasRoutesFile $hasAutoDiscovery) -}} | ||
| {{- fail "pathRouting.enabled is true but pathRouting.routes is empty and no routesFile is set. The firewall would deploy with no routes and return 404 for all traffic. Define pathRouting.routes, set pathRouting.routesFile, or enable pathRouting.privateRegistry auto-discovery." -}} | ||
| {{- end -}} | ||
| {{- end -}} | ||
|
|
||
| {{- /* ElastiCache cluster-mode configuration endpoints (clustercfg.*) hand out | ||
| MOVED redirects across shards. The firewall's Redis client is a | ||
| single-endpoint client and cannot follow them, so every cache operation | ||
| fails at runtime even though the deployment looks healthy. */ -}} | ||
| {{- if $redis.enabled -}} | ||
| {{- $redisHost := (toString ($redis.host | default "")) | trimAll " " -}} | ||
| {{- if hasPrefix "clustercfg." $redisHost -}} | ||
| {{- fail (printf "redis.host %q is an ElastiCache cluster-mode configuration endpoint (clustercfg.*). The firewall uses a single-endpoint Redis client and cannot follow the MOVED redirects a cluster-mode-enabled group issues, so caching would fail at runtime. Use a cluster-mode-disabled replication group and point redis.host at its primary endpoint." $redisHost) -}} | ||
| {{- end -}} | ||
| {{- end -}} | ||
|
|
||
| {{- /* The deployment always mounts SOCKET_SECURITY_API_TOKEN from a Secret, | ||
| but the chart only creates that Secret when socket.apiToken is set. | ||
| With neither value the pods reference a Secret that doesn't exist and | ||
| stay stuck in CreateContainerConfigError. */ -}} | ||
| {{- if and (empty $socket.apiToken) (empty $socket.existingSecret) -}} | ||
| {{- fail "Set socket.apiToken or socket.existingSecret. The deployment mounts SOCKET_SECURITY_API_TOKEN from a Secret; without either value the pods reference a Secret Helm does not create. If you manage that Secret out of band, set socket.existingSecret to its name." -}} | ||
| {{- end -}} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API test ignores egress settings
Medium Severity
Check 2 curls
socket.apiUrlfrom the test pod and requires exactly HTTP 401. It does not usesocket.outboundProxy,socket.apiSslCaCert, orsocket.apiSslVerify, so a working firewall behind a corporate proxy or custom CA still failshelm test.Reviewed by Cursor Bugbot for commit b0eccdb. Configure here.