1d223e85ea3555571a3343cc99edb6893112a821
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
ee9ae8a724
|
feat!: NetworkPolicy in six more charts, on by default
Install-test / Install-test apache-tika (pull_request) Successful in 1m21s
Install-test / Install-test bentopdf (pull_request) Successful in 1m16s
Install-test / Install-test cyberchef (pull_request) Successful in 1m6s
Install-test / Install-test gotenberg (pull_request) Successful in 1m32s
Install-test / Install-test outline (pull_request) Failing after 1m16s
Install-test / Install-test rss-bridge (pull_request) Successful in 1m1s
Install-test / Install-test searxng (pull_request) Successful in 1m13s
Validate Helm Charts / Install-test (pull_request) Failing after 9m57s
Install-test / Install-test ytdlp-web-player (pull_request) Successful in 1m11s
Validate Helm Charts / Detect changed charts (pull_request) Successful in 3s
Validate Helm Charts / Resource quantities (pull_request) Failing after 18s
Validate Helm Charts / HTTPRoute match (pull_request) Failing after 13s
Validate Helm Charts / Selector match (pull_request) Failing after 17s
Validate Helm Charts / Bump level (pull_request) Successful in 8s
Validate Helm Charts / YAML scalars (pull_request) Failing after 16s
Validate Helm Charts / NetworkPolicy (pull_request) Failing after 9s
Validate Helm Charts / Build apache-tika (pull_request) Successful in 5s
Validate Helm Charts / Trivy config apache-tika (pull_request) Successful in 13s
Validate Helm Charts / Build bentopdf (pull_request) Successful in 5s
Validate Helm Charts / Build cyberchef (pull_request) Successful in 6s
Validate Helm Charts / Build outline (pull_request) Successful in 5s
Validate Helm Charts / Build template-chart (pull_request) Successful in 5s
Validate Helm Charts / Trivy config outline (pull_request) Failing after 12s
Validate Helm Charts / Trivy config searxng (pull_request) Successful in 15s
Validate Helm Charts / Trivy config template-chart (pull_request) Successful in 14s
Validate Helm Charts / Build gotenberg (pull_request) Successful in 5s
Validate Helm Charts / Build rss-bridge (pull_request) Successful in 5s
Validate Helm Charts / Build searxng (pull_request) Successful in 5s
Validate Helm Charts / Build ytdlp-web-player (pull_request) Successful in 5s
Validate Helm Charts / Trivy config bentopdf (pull_request) Successful in 14s
Validate Helm Charts / Trivy config cyberchef (pull_request) Successful in 13s
Validate Helm Charts / Trivy config gotenberg (pull_request) Successful in 13s
Validate Helm Charts / Trivy config rss-bridge (pull_request) Successful in 14s
Validate Helm Charts / Trivy config ytdlp-web-player (pull_request) Successful in 15s
bentopdf, apache-tika, gotenberg, rss-bridge, searxng, ytdlp-web-player. One major each, networkPolicy.enabled defaults to true. Three of them differ from the simple case in ways worth naming: GOTENBERG gets DNS-only egress as a deliberate, documented trade. It drives a headless Chromium, and 3000 is its probe port - so it is reachable from the whole cluster by default, and an egress rule for 80/443 would turn a service anyone can POST to into a way of fetching arbitrary URLs. The price is the remote-asset half of HTML conversion: inline content converts, images the page would have fetched silently do not. That degrades a PDF instead of failing a pod, so nothing alerts on it, which is why it is in the template header, in values.yaml and in NOTES.txt, with extraPorts: [80, 443] named as the knowing opt-in. RSS-BRIDGE, SEARXNG and YTDLP-WEB-PLAYER get the open internet on their web ports, because reaching other people's servers IS the application and this object cannot name a host. Said plainly in each, so none of them reads stricter than it is. What the cap still buys is real: no other outbound port, so a compromised pod reaches no database, no mail server and no SSH anywhere. APACHE-TIKA and GOTENBERG render no Ingress - their consumers are other pods, in other namespaces here - so neither gets an ingressController value and both say in NOTES.txt that narrowing probeSources means listing the consumers' namespaces in allowedNamespaces in the same change, or extraction and conversion stop. YTDLP-WEB-PLAYER names the gap this convention has: its oauth2-proxy subchart renders its own Deployment with its own labels and ships no policy, so with the proxy enabled the pod that actually faces the Ingress is unrestricted in both directions. Nothing in this chart can change that - an upstream chart is consumed as it comes - so it is written down instead. ci/outline/test-values.yaml gains egress.extraPorts: [5556]. The CI dex runs there rather than on 443, and Outline fetches the discovery document at boot - so this is the chart's documented escape hatch used for exactly the case it was written for, and the one place in the repo where the cap's upgrade risk is actually exercised. Part of #5 |
||
|
|
e4b41577ae
|
feat(ytdlp-web-player): Gateway-API as an alternative to the Ingress
Group 3 of the #114 sweep, last chart - and the one that carried the group-2 pattern this sweep was told to look for. It reads ingress.enabled OUTSIDE its Ingress template, in ytdlp-web-player.validate, and in Gateway mode ingress.enabled is false by construction, so that guard would have gone silent. Fixed with ytdlp-web-player.published = ingress.enabled OR httpRoute.enabled - the freesailarr.published / sure.publishedOverTls shape, identical to ingress.enabled while httpRoute.enabled is false, which is why it changes no existing render. AND THE GUARD IS NEEDED MORE IN GATEWAY MODE, NOT LESS. It refuses to publish the application and the oauth2-proxy on the same host: - In INGRESS mode the consequence of ignoring it is loud: ingress-nginx's admission webhook rejects the second Ingress and the Fleet bundle goes to ErrApplied. - In GATEWAY mode THE WEBHOOK NEVER FIRES. It compares Ingress objects with Ingress objects, and an HTTPRoute is a different kind - so nothing rejects anything, both objects stay valid, and one hostname is served over two data paths that are NOT equivalent: the proxy's Ingress goes through AUTHENTICATION and this chart's HTTPRoute goes straight to the application. Which one a client reaches depends on what DNS resolves to. That is an authentication bypass that comes and goes with a DNS record and that no Kubernetes object reports. So the Gateway-mode abort has its own message saying exactly that. Both messages exercised, plus the collision reached through httpRoute.hostnames rather than through the ingress.domain fallback, and the guard still firing when only the Deployment is rendered. THE SUBCHART HAS NO GATEWAY SUPPORT, and this chart cannot give it one - upstream's chart is consumed as it comes (README, "Chart dependencies"). It renders an Ingress or nothing. So in the RECOMMENDED configuration, where the proxy sits in the data path and owns the host, the publishing object is the SUBCHART'S INGRESS in both of this chart's modes, and turning httpRoute on buys nothing. The route is for the proxy-disabled case, or for the application on a host of its own - which is the documented unauthenticated bypass. Said in the template header, in values.yaml, in the schema and in the proxy branch of NOTES.txt, because someone migrating hosts will otherwise set the value and wonder why nothing moved. The 16k proxy-buffer-size this chart recommends is NOT lost by this switch, and that needed stating rather than assuming: it belongs on the PROXY's Ingress (oauth2-proxy.ingress.annotations) as the second half of the 4kB session-cookie trap, and the subchart keeps rendering an Ingress. This chart's own ingress.annotations default is {} and it sets nothing but the cert-manager annotation, so there is no chart-side annotation loss to name. CORRECTED CLAIM: values.yaml and the schema both said that everything the Ingress needs is read only inside its template, so switching it off freed BOTH ingress.domain and ingress.clusterIssuer. clusterIssuer is still freed; domain is now read by the HTTPRoute, so it is freed only with both modes off. The reason the claim was made still holds and is kept - the application has no base-URL setting and builds no absolute links. NOTHING WAS MEASURED ON A LIVE INGRESS OF THIS CHART, because there is none. Measured 2026-10-12: the release runs in namespace jlab-player with both Deployments Ready, and NOT ONE of the cluster's 23 Ingress objects is in that namespace - neither this chart's nor the subchart's. What publishes it instead could not be determined: this workspace's identity may not list httproutes or secrets, so neither a hand-written HTTPRoute nor the release's Helm values are readable. Recorded as the open question it is, in values.yaml and in the overlay, rather than guessed at. Minor: additive, defaults unchanged. Empty helm template diff against origin/main with ci/ytdlp-web-player/test-values.yaml. Part of #114 |
||
|
|
6b0d8c9232
|
ytdlp-web-player: new chart with an optional oauth2-proxy subchart (1.0.0+upv1.2.0)
Deploys matszwe02/ytdlp_web_player, a Flask app that fetches videos with
yt-dlp, transcodes them with ffmpeg and serves them as HLS. It ships no
authentication of any kind, so the chart carries a preconfigured oauth2-proxy
as an optional subchart, in the data path in front of the app.
This is the first chart in the repo with a dependency, so the rule "charts
have no dependencies" falls here. It is replaced in CLAUDE.md and README.md by
a bar: a dependency has to be optional and off by default, upstream's chart is
consumed as it comes (documented where it falls short of our conventions,
never patched), and the price is written down - above all that a subchart is
invisible to everything downstream watching Helm release versions, so a new
proxy release only reaches a cluster when this chart is republished.
CI learns the dependency in five places, not the three the plan expected:
helm lint, package, template and install all exit 1 while charts/ is unfilled,
so ci/helm-dependencies.sh runs before lint and package in validate-charts.yml,
before package in publish-helm-chart.yml, and inside run-install-test.sh,
run-trivy-config.sh and run-quantity-render-test.sh - the last of which renders
every chart on every PR and would have gone red first.
Notable chart decisions, each measured rather than assumed:
- The image has no USER and runs as root by default, but not by necessity: it
runs under an arbitrary uid with readOnlyRootFilesystem and the full
hardening baseline. Only the pinned uid is a deviation, and it is documented.
- Two emptyDirs, each justified separately. /data holds the video cache
(DATA_PATH). /tmp is NOT mounted - measured across metadata extraction, HLS
transcoding, sprite generation and audio extraction, the image never writes
there. What it does write is $HOME/.cache, so /cache is mounted with HOME and
XDG_CACHE_HOME pointed at it; without it yt-dlp re-downloads its JavaScript
challenge-solver from github.com on every extraction.
- The proxy is wired through config.configFile, the only value the subchart
passes through tpl - config.upstreams is emitted with toJson and would carry
a literal {{ .Release.Name }} into the manifest.
- Rendering aborts when this chart's Ingress and the proxy's claim the same
host: ingress-nginx rejects the second one and a Fleet bundle then sits in
ErrApplied until forceSyncGeneration is bumped.
Fixes #214
|