Files
K3S/addons/ext-proxy/role/chart/templates/ingress.yaml
Sergey Antropoff aae7941416 feat: добавить аддон ext-proxy — проксировать внешние сервисы через ingress-nginx
Helm chart (один чарт создаёт Service + Endpoints + Ingress на каждый прокси):
- _helpers.tpl: хелперы ext-proxy.resourceName, ext-proxy.labels
- service.yaml: ClusterIP без selector — имя совпадает с Endpoints
- endpoints.yaml: внешние IP(s) + порт; несколько IP → round-robin через kube-proxy
- ingress.yaml: слияние аннотаций (defaults → сгенерированные → уровень прокси);
  поддержка TLS, basic auth, WebSocket, несколько хостов, маршрутизация по пути
- secret-auth.yaml: htpasswd Secret создаётся только при auth.enabled=true + credentials
- NOTES.txt: список прокси + команды проверки после установки

Ansible роль:
- defaults/main.yml: ext_proxy_namespace, ext_proxy_defaults, ext_proxy_proxies
- tasks/main.yml: валидация → namespace → копировать chart → lint → helm upgrade --install --atomic
- templates/values.yaml.j2: преобразование Ansible-переменных в Helm values через to_yaml

Интеграция: Makefile addon-ext-proxy, флаг addons.yml, playbooks/addons.yml,
            docs/addons.md, README.md (счётчик 37 аддонов)

README.md на русском языке с полной документацией:
архитектура, настройка, функции, DNS, проверка, примеры манифестов, устранение неисправностей

Дополнительно: splitgw_deploy_mode изменён на k8s
2026-04-26 07:21:41 +03:00

132 lines
5.6 KiB
YAML

{{/*
Creates one Ingress per proxy entry.
Feature resolution order (highest → lowest priority):
1. Per-proxy annotations (.proxies[*].annotations) — override everything
2. Per-proxy feature flags (websocket, auth, tls…)
3. Global defaults (.defaults.*)
4. Built-in generated annotations (timeouts, body-size)
Annotation merge is done via successive dict mutations so that
per-proxy annotations always win, with no duplicate YAML keys.
*/}}
{{- range .Values.proxies }}
{{- $proxy := . }}
{{- $d := $.Values.defaults }}
{{- $proxyName := include "ext-proxy.resourceName" $proxy.name }}
{{/* ── Resolve per-proxy settings with fallback to defaults ────────────────── */}}
{{- $ingressClass := $proxy.ingressClass | default $d.ingressClass | default "nginx" }}
{{- $path := $proxy.path | default $d.path | default "/" }}
{{- $pathType := $proxy.pathType | default $d.pathType | default "Prefix" }}
{{- $connectTO := $proxy.proxyConnectTimeout | default $d.proxyConnectTimeout | default 60 }}
{{- $readTO := $proxy.proxyReadTimeout | default $d.proxyReadTimeout | default 3600 }}
{{- $sendTO := $proxy.proxySendTimeout | default $d.proxySendTimeout | default 3600 }}
{{- $bodySize := $proxy.proxyBodySize | default $d.proxyBodySize | default "1g" }}
{{/* websocket: check proxy first, then default, then true */}}
{{- $websocket := true }}
{{- if ne ($proxy.websocket | toString) "<nil>" }}
{{- $websocket = $proxy.websocket }}
{{- else if ne ($d.websocket | toString) "<nil>" }}
{{- $websocket = $d.websocket }}
{{- end }}
{{/* ── TLS: merge proxy-level overrides onto global defaults ───────────────── */}}
{{- $proxyTLS := $proxy.tls | default dict }}
{{- $defTLS := $d.tls | default dict }}
{{- $proxyCM := $proxyTLS.certManager | default dict }}
{{- $defCM := $defTLS.certManager | default dict }}
{{- $tlsEnabled := $proxyTLS.enabled | default $defTLS.enabled | default false }}
{{- $tlsSecret := $proxyTLS.secretName | default $defTLS.secretName | default "" }}
{{- $cmEnabled := $proxyCM.enabled | default $defCM.enabled | default false }}
{{- $cmIssuer := $proxyCM.issuer | default $defCM.issuer | default "" }}
{{- $cmKind := $proxyCM.issuerKind | default $defCM.issuerKind | default "ClusterIssuer" }}
{{/* ── Auth: merge proxy-level overrides onto global defaults ─────────────── */}}
{{- $proxyAuth := $proxy.auth | default dict }}
{{- $defAuth := $d.auth | default dict }}
{{- $authEnabled := $proxyAuth.enabled | default $defAuth.enabled | default false }}
{{- $authSecret := "" }}
{{- if $authEnabled }}
{{- $authSecret = $proxyAuth.secretName | default $defAuth.secretName | default (printf "%s-auth" $proxyName) }}
{{- end }}
{{/* ── Hosts: support .hosts list or single .host string ─────────────────── */}}
{{- $hosts := $proxy.hosts | default (list ($proxy.host | default "")) }}
{{/* ── Build annotation dict ───────────────────────────────────────────────── */}}
{{- $ann := dict }}
{{/* Step 1: global default annotations (lowest priority) */}}
{{- range $k, $v := ($d.annotations | default dict) }}
{{- $_ := set $ann $k ($v | toString) }}
{{- end }}
{{/* Step 2: generated feature annotations */}}
{{- $_ := set $ann "nginx.ingress.kubernetes.io/proxy-connect-timeout" ($connectTO | toString) }}
{{- $_ := set $ann "nginx.ingress.kubernetes.io/proxy-read-timeout" ($readTO | toString) }}
{{- $_ := set $ann "nginx.ingress.kubernetes.io/proxy-send-timeout" ($sendTO | toString) }}
{{- $_ := set $ann "nginx.ingress.kubernetes.io/proxy-body-size" $bodySize }}
{{/* WebSocket: enable HTTP/1.1 keep-alive required for Upgrade handshake */}}
{{- if $websocket }}
{{- $_ := set $ann "nginx.ingress.kubernetes.io/proxy-http-version" "1.1" }}
{{- end }}
{{/* Basic auth */}}
{{- if $authEnabled }}
{{- $_ := set $ann "nginx.ingress.kubernetes.io/auth-type" "basic" }}
{{- $_ := set $ann "nginx.ingress.kubernetes.io/auth-secret" $authSecret }}
{{- $_ := set $ann "nginx.ingress.kubernetes.io/auth-realm" "Authentication Required" }}
{{- end }}
{{/* cert-manager: add ClusterIssuer/Issuer annotation */}}
{{- if $cmEnabled }}
{{- $cmAnnotationKey := printf "cert-manager.io/%s" ($cmKind | lower) }}
{{- $_ := set $ann $cmAnnotationKey $cmIssuer }}
{{- end }}
{{/* Step 3: per-proxy custom annotations override everything above */}}
{{- range $k, $v := ($proxy.annotations | default dict) }}
{{- $_ := set $ann $k ($v | toString) }}
{{- end }}
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $proxyName }}
namespace: {{ $.Release.Namespace }}
labels:
{{- include "ext-proxy.labels" $ | nindent 4 }}
app.kubernetes.io/component: {{ $proxyName }}
annotations:
{{- toYaml $ann | nindent 4 }}
spec:
ingressClassName: {{ $ingressClass }}
{{- if $tlsEnabled }}
tls:
- hosts:
{{- range $hosts }}
- {{ . | quote }}
{{- end }}
{{- if $tlsSecret }}
secretName: {{ $tlsSecret | quote }}
{{- end }}
{{- end }}
rules:
{{- range $hosts }}
- host: {{ . | quote }}
http:
paths:
- path: {{ $path | quote }}
pathType: {{ $pathType }}
backend:
service:
name: {{ $proxyName }}
port:
number: {{ $proxy.port }}
{{- end }}
{{- end }}