{{- $httpRoute := .Values.httpRoute | default dict -}}
{{- $hostnames := $httpRoute.hostnames | default list -}}
RSS-Bridge {{ .Chart.AppVersion }} was installed as release "{{ .Release.Name }}".

{{ if .Values.ingress.enabled -}}
ACCESS - INGRESS MODE (ingress.enabled: true, httpRoute.enabled: false)

Reachable at:
{{ range $entry := .Values.ingress.hosts }}  https://{{ $entry.host }}
{{ end }}
Each host serves the same instance. Certificates are issued by the
cert-manager cluster issuer "{{ .Values.ingress.clusterIssuer }}" into these secrets:
{{ range $secret := (fromYaml (include "rss-bridge.tlsGroups" (dict "hosts" .Values.ingress.hosts "root" $))).order }}  {{ $secret }}
{{ end }}
Hosts sharing a secret name share one certificate with several SANs; hosts with
distinct names get one certificate each. That grouping is what keeps the three
grown certificates of this installation on their existing secret names.
{{- else if $httpRoute.enabled -}}
ACCESS - GATEWAY MODE (httpRoute.enabled: true, ingress.enabled: false)

Reachable at:
{{ range $hostnames }}  https://{{ . }}
{{ end }}
All of these names are served by ONE HTTPRoute ({{ .Release.Name }}-{{ .Chart.Name }}-httproute), because
nothing differs between them: one rule, PathPrefix "/", one backend. Adding or
removing a name is an edit to httpRoute.hostnames and nothing else.

This release renders that route and NOTHING else of the routing path - no
Gateway, no class, no Certificate. Three things therefore belong to the cluster
and not to this chart, and if any of them is missing the hostnames above simply
do not answer:

  1. The Gateway-API CRDs. Without them this install would have failed, so
     they are present - nothing to check.
  2. The Gateway named in httpRoute.parentRefs
{{- range $httpRoute.parentRefs }}
       {{ .name }}{{ if .namespace }} in namespace {{ .namespace }}{{ end }}{{ if .sectionName }}, listener {{ .sectionName }}{{ end }}
{{- end }}
     must exist AND its listener must allow routes from this namespace
     ({{ .Release.Namespace }}) in allowedRoutes. A rejected attachment is
     visible only in the route's status:

       kubectl -n {{ .Release.Namespace }} get httproute {{ .Release.Name }}-{{ .Chart.Name }}-httproute -o yaml

     Read status.parents[].conditions - "Accepted: True" and
     "ResolvedRefs: True" is what a working attachment looks like. An empty
     status means no controller has looked at the route at all.
  3. A TLS certificate for every hostname above, on the Gateway's listener.
     ingress.clusterIssuer is NOT used in this mode and is not required - the
     chart renders no Certificate here, so none of the tls-* secrets listed by
     the Ingress mode exists and there is nothing for cert-manager to do on
     behalf of this release.

NOTHING THIS CHART DID IN INGRESS MODE IS LOST HERE

Worth stating plainly, because it is not the usual case in this repository:
most charts switched to the Gateway API give something up, since
ingress.annotations has no counterpart in this API and an operator's
annotation often carried real behaviour. This chart's live Ingress was measured
before the switch and carries no nginx.ingress.kubernetes.io annotation at all -
no body-size limit, no buffer sizes, no CORS, no rewrite, no auth. So there is
no compensation to re-create at the Gateway and no behaviour to miss.

Two things do become inert, and neither is a loss:

  * ingress.annotations - gone in this mode, as everywhere. Empty here.
  * The TLS secret grouping (rss-bridge.tlsGroups, and the per-host
    ingress.hosts[].tlsSecretName it reads) - with the certificate on the
    listener there is nothing left to group. This is the chart's most
    intricate Ingress-mode machinery and it simply has no job here.

What is NOT demonstrated: that traffic actually flows. No Gateway controller
runs in CI, so no HTTPRoute of this chart has ever reached "Accepted: True"
there, and the install-test installs the Ingress mode rather than this one.
Check the route status above after the first install rather than assuming it
attached.
{{- else -}}
ACCESS - NEITHER INGRESS NOR HTTPROUTE

ingress.enabled and httpRoute.enabled are both false, so this release has no
Ingress, no HTTPRoute and no certificate; ingress.hosts, ingress.clusterIssuer
and httpRoute.hostnames are not needed. Reach the instance with:

  kubectl --namespace {{ .Release.Namespace }} port-forward svc/{{ .Release.Name }}-{{ .Chart.Name }}-service 8080:80

and open http://localhost:8080

To publish it instead, set either ingress.enabled=true with ingress.hosts and
ingress.clusterIssuer, or httpRoute.enabled=true with httpRoute.hostnames and
httpRoute.parentRefs.
{{- end }}

Enabled bridges ({{ len .Values.whitelist }} entr{{ if eq (len .Values.whitelist) 1 }}y{{ else }}ies{{ end }} in whitelist.txt):
{{ range $entry := .Values.whitelist }}  {{ $entry }}
{{ end }}
{{- if has "*" .Values.whitelist }}
"*" enables every bridge the image ships. Narrow it down by listing bridge
names in the "whitelist" value.
{{- end }}

Useful to know:

  * Health endpoint: /?action=health - a fixed JSON document that touches
    neither the cache nor any remote site. All three probes use it.
  * Changing the "whitelist" value rolls the pod: the deployment carries a
    checksum over the ConfigMap, because a subPath mount would otherwise never
    reach the running container.
  * The feed cache lives in an emptyDir at /app/cache and is therefore
    deliberately lost on every restart. RSS-Bridge refills it on demand; it
    holds only fetched feeds, no configuration and no user data.
  * The container runs read-only and non-root as uid 33 (www-data).
{{- if .Values.scaleDown }}

WARNING: scaleDown is true, so this release is running with 0 replicas.
Set scaleDown=false to bring it back up.
{{- end }}
{{- if .Values.networkPolicy.enabled }}

NETWORKPOLICY IS ACTIVE — WHAT IT CAPS, AND WHAT IT DOES NOT
  {{ .Release.Name }}-{{ .Chart.Name }}-networkpolicy selects this workload's pods.
  Inbound: TCP 80 only. Outbound: DNS plus TCP 80 and 443 to ANY destination{{ with .Values.networkPolicy.egress }}{{ with .extraPorts }},
  plus TCP {{ join ", " . }}{{ end }}{{ end }}.

  THE EGRESS RULE IS THE OPEN INTERNET ON TWO PORTS, and it has to be: fetching
  other people's websites is what RSS-Bridge does, and a NetworkPolicy matches
  CIDRs and selectors but never hostnames, so "only the configured bridges"
  cannot be written. What the cap buys is that this pod can open NO other
  outbound port — not a database, not SMTP, not SSH.

  Three limits belong in the same breath, because none of them is visible in
  the object itself:

  - EGRESS IS BY PORT, NEVER BY DESTINATION. A NetworkPolicy matches CIDRs and
    selectors and cannot express a hostname, so every egress rule permits its
    port to ANY address. That is a limit of the object, not a shortcut — this
    cluster's CNI (Canal: Flannel plus Calico) has no FQDN rule either. An
    outbound port the chart does not know about is BLOCKED: add it to
    networkPolicy.egress.extraPorts, and expect to find out through an
    application-level connection error rather than through this object.
{{- if .Values.networkPolicy.probeSources }}
  - THE PROBE PATH IS RESTRICTED in this release, because
    networkPolicy.probeSources is set to
      {{ join ", " .Values.networkPolicy.probeSources }}
    Probes come from the IP of the WORKER NODE running the pod. If none of those
    CIDRs covers the node this pod lands on, the kubelet's probes are dropped
    and THE POD NEVER BECOMES READY — the rollout then times out and the symptom
    looks like a broken application. Compare

      kubectl -n {{ .Release.Namespace }} describe pod -l app={{ .Release.Name }}-{{ .Chart.Name }}-deployment

    against `kubectl get node -o wide`.
{{- else }}
  - THE PROBED PORT IS OPEN INSIDE THE CLUSTER. networkPolicy.probeSources is
    empty, so that rule carries no source selector at all and any pod the CNI
    routes to can reach it. Not from the internet — but this is NOT pod-level
    isolation. Narrowing it means listing the worker node IPs in
    networkPolicy.probeSources, because the kubelet probes from the node's own
    address and the chart cannot know it; a wrong guess there leaves the pod
    permanently un-Ready.
{{- end }}
  - IT IS ONLY A BOUNDARY WHERE THE CNI ENFORCES POLICIES. Where it does not,
    this object is accepted and filters nothing, so everything reads as
    configured while nothing is filtered. `kubectl -n {{ .Release.Namespace }} get networkpolicy`
    shows the object exists; only a connection attempt from an unrelated
    namespace shows that it bites.

  Switch it off with networkPolicy.enabled: false.
{{- end }}
