- addons/ext-proxy/ → addons/ingress-proxypass/ (git mv, история сохранена) - Все переменные Ansible: ext_proxy_* → ingress_proxypass_* - Все имена ресурсов K8s: ext-proxy → ingress-proxypass (namespace, chart, release) - Helm-хелперы: "ext-proxy.*" → "ingress-proxypass.*" - Makefile: addon-ext-proxy → addon-ingress-proxypass - group_vars/all/addons.yml: addon_ext_proxy → addon_ingress_proxypass - playbooks/addons.yml: обновлена ссылка на роль - docs/addons.md, README.md: обновлены все упоминания
194 lines
8.3 KiB
YAML
194 lines
8.3 KiB
YAML
---
|
||
# ── Validate inputs ───────────────────────────────────────────────────────────
|
||
|
||
- name: Validate ingress_proxypass_proxies is defined and non-empty
|
||
ansible.builtin.assert:
|
||
that:
|
||
- ingress_proxypass_proxies is defined
|
||
- ingress_proxypass_proxies | length > 0
|
||
fail_msg: >
|
||
ingress_proxypass_proxies is empty. Define at least one proxy in
|
||
group_vars/all/addons.yml → ingress_proxypass_proxies.
|
||
success_msg: "ingress_proxypass_proxies: {{ ingress_proxypass_proxies | length }} service(s) defined"
|
||
|
||
# ── Create namespace ──────────────────────────────────────────────────────────
|
||
|
||
- name: Create ingress-proxypass namespace
|
||
ansible.builtin.command: >
|
||
k3s kubectl create namespace {{ ingress_proxypass_namespace }}
|
||
--dry-run=client -o yaml | k3s kubectl apply -f -
|
||
become: true
|
||
changed_when: false
|
||
|
||
# ── Copy Helm chart to master node ───────────────────────────────────────────
|
||
|
||
- name: Ensure chart temp directory is clean
|
||
ansible.builtin.file:
|
||
path: /tmp/ingress-proxypass-chart
|
||
state: absent
|
||
become: true
|
||
|
||
- name: Create chart temp directory
|
||
ansible.builtin.file:
|
||
path: /tmp/ingress-proxypass-chart
|
||
state: directory
|
||
mode: "0755"
|
||
become: true
|
||
|
||
- name: Copy Helm chart to master
|
||
ansible.builtin.copy:
|
||
src: "{{ role_path }}/chart/"
|
||
dest: /tmp/ingress-proxypass-chart/
|
||
mode: preserve
|
||
become: true
|
||
|
||
# ── Generate htpasswd hashes from plain username/password ────────────────────
|
||
# Если auth.username + auth.password заданы — автоматически хэшируем через
|
||
# openssl passwd -apr1, записываем в auth.credentials и убираем открытые поля.
|
||
# Если auth.credentials уже задан — используем его без изменений.
|
||
# Пароли в открытом виде нигде не попадают в Helm values или логи.
|
||
|
||
- name: Generate htpasswd credentials (username/password → apr1 hash)
|
||
ansible.builtin.command:
|
||
argv:
|
||
- python3
|
||
- -c
|
||
- |
|
||
import json, subprocess, sys
|
||
|
||
proxies = json.loads(sys.argv[1])
|
||
def_auth = json.loads(sys.argv[2])
|
||
|
||
def gen_credentials(auth, fallback):
|
||
"""Return htpasswd string or '' if nothing to generate."""
|
||
username = auth.get('username') or fallback.get('username', '')
|
||
password = auth.get('password') or fallback.get('password', '')
|
||
credentials = auth.get('credentials') or fallback.get('credentials', '')
|
||
secret_name = auth.get('secretName') or fallback.get('secretName', '')
|
||
if credentials or secret_name:
|
||
return credentials # уже готово или внешний Secret
|
||
if username and password:
|
||
r = subprocess.run(
|
||
['openssl', 'passwd', '-apr1', password],
|
||
capture_output=True, text=True, check=True
|
||
)
|
||
return username + ':' + r.stdout.strip()
|
||
return ''
|
||
|
||
# Обработать глобальный default auth
|
||
cleaned_def_auth = {k: v for k, v in def_auth.items()
|
||
if k not in ('username', 'password')}
|
||
creds = gen_credentials(def_auth, {})
|
||
if creds:
|
||
cleaned_def_auth['credentials'] = creds
|
||
|
||
# Обработать каждый прокси
|
||
for proxy in proxies:
|
||
auth = dict(proxy.get('auth') or {})
|
||
enabled = auth.get('enabled', def_auth.get('enabled', False))
|
||
if enabled:
|
||
creds = gen_credentials(auth, def_auth)
|
||
if creds:
|
||
auth['credentials'] = creds
|
||
# Убрать открытый текст из итоговых values
|
||
auth.pop('username', None)
|
||
auth.pop('password', None)
|
||
proxy['auth'] = auth
|
||
|
||
print(json.dumps({'proxies': proxies, 'def_auth': cleaned_def_auth}))
|
||
- "{{ ingress_proxypass_proxies | to_json }}"
|
||
- "{{ ingress_proxypass_defaults.auth | to_json }}"
|
||
register: _auth_processed
|
||
changed_when: false
|
||
no_log: true
|
||
|
||
- name: Set final proxies and defaults with generated credentials
|
||
ansible.builtin.set_fact:
|
||
_ingress_proxypass_proxies_final: "{{ (_auth_processed.stdout | from_json).proxies }}"
|
||
_ingress_proxypass_def_auth_final: "{{ (_auth_processed.stdout | from_json).def_auth }}"
|
||
|
||
# ── Template Helm values ──────────────────────────────────────────────────────
|
||
|
||
- name: Template Helm values
|
||
ansible.builtin.template:
|
||
src: values.yaml.j2
|
||
dest: /tmp/ingress-proxypass-values.yaml
|
||
mode: "0640"
|
||
become: true
|
||
|
||
- name: Show generated Helm values
|
||
ansible.builtin.command: cat /tmp/ingress-proxypass-values.yaml
|
||
become: true
|
||
changed_when: false
|
||
register: _ingress_proxypass_values
|
||
|
||
- name: Debug generated values
|
||
ansible.builtin.debug:
|
||
var: _ingress_proxypass_values.stdout_lines
|
||
|
||
# ── Lint chart before deploying ───────────────────────────────────────────────
|
||
|
||
- name: Lint Helm chart
|
||
ansible.builtin.command: >
|
||
helm lint /tmp/ingress-proxypass-chart
|
||
--values /tmp/ingress-proxypass-values.yaml
|
||
become: true
|
||
changed_when: false
|
||
register: _helm_lint
|
||
failed_when: _helm_lint.rc != 0
|
||
|
||
# ── Deploy chart ──────────────────────────────────────────────────────────────
|
||
|
||
- name: Deploy ingress-proxypass via Helm
|
||
ansible.builtin.command: >
|
||
helm upgrade --install {{ ingress_proxypass_release_name }}
|
||
/tmp/ingress-proxypass-chart
|
||
--namespace {{ ingress_proxypass_namespace }}
|
||
--values /tmp/ingress-proxypass-values.yaml
|
||
--atomic
|
||
--wait
|
||
--timeout 60s
|
||
become: true
|
||
register: _helm_result
|
||
changed_when: true
|
||
|
||
# ── Verify deployment ─────────────────────────────────────────────────────────
|
||
|
||
- name: Get Ingress list
|
||
ansible.builtin.command: >
|
||
k3s kubectl -n {{ ingress_proxypass_namespace }} get ingress -o wide
|
||
become: true
|
||
changed_when: false
|
||
register: _ingress_list
|
||
|
||
- name: Get Endpoints list
|
||
ansible.builtin.command: >
|
||
k3s kubectl -n {{ ingress_proxypass_namespace }} get endpoints
|
||
become: true
|
||
changed_when: false
|
||
register: _endpoints_list
|
||
|
||
# ── Summary ───────────────────────────────────────────────────────────────────
|
||
|
||
- name: "=== External Services Ingress Proxy Ready ==="
|
||
ansible.builtin.debug:
|
||
msg:
|
||
- "╔══════════════════════════════════════════════════════════════╗"
|
||
- "║ External Services Ingress Proxy — Deployed ║"
|
||
- "╚══════════════════════════════════════════════════════════════╝"
|
||
- ""
|
||
- " Namespace : {{ ingress_proxypass_namespace }}"
|
||
- " Release : {{ ingress_proxypass_release_name }}"
|
||
- " Services : {{ ingress_proxypass_proxies | length }}"
|
||
- ""
|
||
- " Ingress resources:"
|
||
- "{{ _ingress_list.stdout_lines | to_yaml }}"
|
||
- ""
|
||
- " Endpoints:"
|
||
- "{{ _endpoints_list.stdout_lines | to_yaml }}"
|
||
- ""
|
||
- " kube-vip VIP: {{ ingress_proxypass_vip | default('<check kube-vip>') }}"
|
||
- " → Point all proxy hostnames to the VIP in DNS/hosts file"
|
||
- ""
|
||
- " Verify: kubectl -n {{ ingress_proxypass_namespace }} describe ingress"
|