test: добавить полное покрытие Molecule + HTML report генератор

Molecule тесты для всех аддонов и кластерный topology тест:

Аддоны (Helm lint + template + assertions):
- addons/technitium-dns/role/molecule/ — Primary/Secondary DNS, CronJob, kube-vip
- addons/authelia/role/molecule/ — OIDC clients, access_control, manifests
- addons/ingress-proxypass/role/molecule/ — proxies, Service/Endpoints/Ingress
- addons/ingress-add-domains/role/molecule/ — entries, Ingress per namespace
- addons/yandex-dns-controller/role/molecule/ — CronJob, ConfigMap, RBAC

Кластер:
- molecule/cluster/ — 3 master (embedded etcd HA) + 2 worker topology тест

Инфраструктура:
- scripts/molecule-report.py — генератор HTML отчётов из JUnit XML
  (читает /tmp/molecule-junit/*.xml → /tmp/molecule-report.html)
- requirements-python.txt — комментарий к отчётному блоку
- docker/entrypoint.sh — добавлены команды molecule-addon, molecule-cluster,
  molecule-report с автоматическим включением junit callback
- Makefile — targets: molecule-cluster, molecule-addon-*, molecule-addon-all,
  molecule-report; molecule-all генерирует HTML отчёт
- docs/molecule-testing.md — полная документация всех сценариев
- docs/addons.md — добавлены technitium-dns и authelia в таблицу аддонов
This commit is contained in:
Sergey Antropoff
2026-04-26 18:57:11 +03:00
parent 225f77598a
commit 91299fcc1b
25 changed files with 2376 additions and 72 deletions

View File

@@ -0,0 +1,82 @@
---
- name: Converge — ingress-add-domains template tests
hosts: all
become: false
gather_facts: false
vars:
ingress_add_domains_release_namespace: ingress-add-domains
ingress_add_domains_release_name: ingress-add-domains
ingress_add_domains_defaults:
ingressClass: nginx
tls:
enabled: false
secretName: ""
certManager:
enabled: false
issuer: ""
issuerKind: ClusterIssuer
websocket: false
path: /
pathType: Prefix
annotations: {}
# Pre-resolved auth (normally computed by role tasks via openssl passwd -apr1)
_ingress_add_domains_def_auth_final:
enabled: false
credentials: ""
secretName: ""
# Pre-resolved entries list (normally built by role tasks, merging defaults + per-entry auth)
_ingress_add_domains_entries_final:
- name: gitea-local
hosts:
- gitea.home.local
service:
name: gitea-http
namespace: gitea
port: 3000
auth:
enabled: false
credentials: ""
secretName: ""
- name: grafana-local
hosts:
- grafana.home.local
service:
name: grafana
namespace: monitoring
port: 3000
auth:
enabled: true
credentials: "admin:$apr1$molecule$hashfortesting123456"
secretName: ""
tasks:
- name: Render Helm values
ansible.builtin.template:
src: "{{ playbook_dir }}/../../templates/values.yaml.j2"
dest: /tmp/ingress-add-domains-values.yaml
mode: "0644"
- name: Run helm lint on the chart
ansible.builtin.command: >
helm lint /ansible/addons/ingress-add-domains/role/chart
--values /tmp/ingress-add-domains-values.yaml
--strict
delegate_to: localhost
changed_when: false
register: helm_lint_result
- name: Run helm template to verify manifests
ansible.builtin.command: >
helm template ingress-add-domains /ansible/addons/ingress-add-domains/role/chart
--values /tmp/ingress-add-domains-values.yaml
--namespace ingress-add-domains
delegate_to: localhost
changed_when: false
register: helm_template_result
- name: Save manifests for assertion
ansible.builtin.copy:
content: "{{ helm_template_result.stdout }}"
dest: /tmp/ingress-add-domains-manifests.yaml
mode: "0644"

View File

@@ -0,0 +1,27 @@
---
driver:
name: docker
platforms:
- name: master01
image: geerlingguy/docker-ubuntu2204-ansible:latest
pre_build_image: true
groups:
- k3s_master
provisioner:
name: ansible
playbooks:
converge: converge.yml
verify: verify.yml
config_options:
defaults:
interpreter_python: auto_silent
verifier:
name: ansible
lint: |
set -e
yamllint .
ansible-lint

View File

@@ -0,0 +1,94 @@
---
- name: Verify — ingress-add-domains templates
hosts: all
become: false
gather_facts: false
tasks:
# ── values.yaml.j2 rendering ──────────────────────────────────────────────
- name: Read rendered Helm values
ansible.builtin.slurp:
src: /tmp/ingress-add-domains-values.yaml
register: values_raw
- name: Parse values YAML
ansible.builtin.set_fact:
v: "{{ values_raw.content | b64decode | from_yaml }}"
- name: Assert defaults ingressClass
ansible.builtin.assert:
that: v.defaults.ingressClass == 'nginx'
fail_msg: "defaults.ingressClass неверный: {{ v.defaults.ingressClass }}"
- name: Assert entries list has 2 items
ansible.builtin.assert:
that: v.entries | length == 2
fail_msg: "entries должен содержать 2 записи, получено: {{ v.entries | length }}"
- name: Assert gitea entry has correct service config
ansible.builtin.assert:
that:
- v.entries[0].name == 'gitea-local'
- "'gitea.home.local' in v.entries[0].hosts"
- v.entries[0].service.name == 'gitea-http'
- v.entries[0].service.namespace == 'gitea'
- v.entries[0].service.port == 3000
fail_msg: "gitea entry настроен неверно: {{ v.entries[0] }}"
- name: Assert grafana entry has auth enabled
ansible.builtin.assert:
that:
- v.entries[1].name == 'grafana-local'
- v.entries[1].auth.enabled == true
- v.entries[1].auth.credentials | length > 0
fail_msg: "grafana entry auth настроен неверно: {{ v.entries[1] }}"
# ── Helm manifests ────────────────────────────────────────────────────────
- name: Read rendered manifests
ansible.builtin.slurp:
src: /tmp/ingress-add-domains-manifests.yaml
register: manifests_raw
- name: Set manifests content fact
ansible.builtin.set_fact:
manifests: "{{ manifests_raw.content | b64decode }}"
- name: Assert Ingress resources are rendered
ansible.builtin.assert:
that: "'kind: Ingress' in manifests"
fail_msg: "Ingress не найден в manifests"
- name: Assert gitea ingress host is present
ansible.builtin.assert:
that: "'gitea.home.local' in manifests"
fail_msg: "gitea.home.local не найден в Ingress"
- name: Assert grafana ingress host is present
ansible.builtin.assert:
that: "'grafana.home.local' in manifests"
fail_msg: "grafana.home.local не найден в Ingress"
- name: Assert gitea backend service name is in Ingress
ansible.builtin.assert:
that: "'gitea-http' in manifests"
fail_msg: "Service gitea-http не найден в Ingress backend"
- name: Assert gitea is in gitea namespace
ansible.builtin.assert:
that: "'namespace: gitea' in manifests"
fail_msg: "Ingress не размещён в namespace gitea"
- name: Assert grafana auth Secret is rendered
ansible.builtin.assert:
that: "'kind: Secret' in manifests"
fail_msg: "Secret для basic auth не найден (grafana entry имеет auth.enabled=true)"
- name: Assert nginx auth-type annotation is in grafana Ingress
ansible.builtin.assert:
that: "'auth-type' in manifests"
fail_msg: "nginx.ingress.kubernetes.io/auth-type аннотация не найдена"
- name: Assert nginx ingressClass is set
ansible.builtin.assert:
that: "'ingressClassName: nginx' in manifests"
fail_msg: "ingressClassName: nginx не найден в manifests"