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:
@@ -70,6 +70,9 @@ make addon-netbird
|
||||
| ingress-proxypass | `addon_ingress_proxypass` | Проксировать внешние сервисы (IP:PORT) через ingress-nginx по домену — Service + Endpoints + Ingress | [→](../addons/ingress-proxypass/README.md) |
|
||||
| ingress-add-domains | `addon_ingress_add_domains` | Добавить домены к существующим K8s сервисам — только Ingress, без Service/Endpoints | [→](../addons/ingress-add-domains/README.md) |
|
||||
| yandex-dns-controller | `addon_yandex_dns_controller` | CronJob-контроллер Yandex 360 DNS — ConfigMap → DNS, safe mode (managed:true only) | [→](../addons/yandex-dns-controller/README.md) |
|
||||
| technitium-dns | `addon_technitium_dns` | HA DNS: Primary + Secondary с kube-vip LB, авто-sync зон, ExternalDNS (RFC 2136) | [→](../addons/technitium-dns/README.md) |
|
||||
| **SSO / Auth** | | | |
|
||||
| authelia | `addon_authelia` | SSO Forward-auth + OIDC provider: Gitea, Grafana, ArgoCD, MinIO, Vault, Nextcloud | [→](../addons/authelia/README.md) |
|
||||
|
||||
## Конфигурация addons.yml
|
||||
|
||||
@@ -123,6 +126,13 @@ addon_splitgw: false # sing-box + Hysteria2 TPROXY (host или k8
|
||||
# ── External Services Ingress Proxy ───────────────────────────────────────────
|
||||
addon_ingress_proxypass: false # проксировать внешние сервисы через ingress-nginx
|
||||
addon_ingress_add_domains: false # добавить домены к существующим K8s сервисам (только Ingress)
|
||||
|
||||
# ── DNS ───────────────────────────────────────────────────────────────────────
|
||||
addon_yandex_dns_controller: false # Yandex 360 DNS controller (managed records)
|
||||
addon_technitium_dns: false # HA DNS сервер (Primary+Secondary, kube-vip)
|
||||
|
||||
# ── SSO ───────────────────────────────────────────────────────────────────────
|
||||
addon_authelia: false # SSO Forward-auth + OIDC (Gitea/Grafana/ArgoCD/...)
|
||||
```
|
||||
|
||||
## Зависимости между аддонами
|
||||
@@ -144,6 +154,9 @@ addon_ingress_add_domains: false # добавить домены к с
|
||||
| `mediaserver` | `csi-nfs` (рекомендуется) | Shared PVC требует RWX StorageClass |
|
||||
| `splitgw` | Hysteria2 сервер (vault_hysteria2_url) | URL из Shadowrocket / NekoBox |
|
||||
| `ingress-proxypass` | `ingress-nginx` | Требует работающий Ingress controller |
|
||||
| `ingress-add-domains` | `ingress-nginx` | Требует работающий Ingress controller |
|
||||
| `technitium-dns` | kube-vip | LoadBalancer IP через kube-vip аннотацию |
|
||||
| `authelia` | `ingress-nginx` | Forward-auth через annotations; PostgreSQL/Redis — опционально |
|
||||
|
||||
## MediaServer
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Тестирование через Molecule
|
||||
|
||||
Molecule — стандартный инструмент для тестирования Ansible ролей. Каждая роль запускается в Docker-контейнерах, проходит набор автоматических проверок и удаляется. Реальные серверы не нужны.
|
||||
Molecule — стандартный инструмент для тестирования Ansible ролей и аддонов. Каждый сценарий запускается в Docker-контейнерах, проходит набор автоматических проверок и удаляется. Реальные серверы не нужны.
|
||||
|
||||
## Требования
|
||||
|
||||
@@ -8,38 +8,95 @@ Molecule — стандартный инструмент для тестиров
|
||||
|
||||
```bash
|
||||
make build # собрать образ (один раз)
|
||||
make molecule-k3s # запустить тест
|
||||
make molecule-k3s # запустить тест роли k3s
|
||||
```
|
||||
|
||||
Как это работает: `make molecule-*` запускает контейнер `k3s-ansible` с примонтированным Docker socket. Внутри этого контейнера Molecule создаёт тестовые контейнеры — Docker внутри Docker без демона (только socket от хоста).
|
||||
Как это работает: `make molecule-*` запускает контейнер `k3s-ansible` с примонтированным Docker socket. Внутри этого контейнера Molecule создаёт тестовые контейнеры — Docker-in-Docker без демона (только socket от хоста).
|
||||
|
||||
## Доступные тесты
|
||||
---
|
||||
|
||||
## Все доступные тесты
|
||||
|
||||
```bash
|
||||
make molecule-k3s # Роль k3s — 3 ноды: master01, worker01, rpi01 (~8-12 мин)
|
||||
make molecule-prometheus # Роль prometheus-stack (~2-3 мин)
|
||||
make molecule-istio # Роль istio (~2-3 мин)
|
||||
make molecule-all # Все тесты последовательно (~15-20 мин)
|
||||
make molecule-lint # Линтинг YAML + ansible-lint (~30 сек)
|
||||
# ─── Роли ──────────────────────────────────────────────────────────────────
|
||||
make molecule-k3s # роль k3s — 3 ноды (master + worker + Debian), ~8-12 мин
|
||||
make molecule-prometheus # роль prometheus-stack (Helm values шаблоны), ~2-3 мин
|
||||
make molecule-istio # роль istio + kiali (4 шаблона), ~2-3 мин
|
||||
|
||||
# ─── Кластер (3 master + 2 worker, embedded etcd HA) ───────────────────────
|
||||
make molecule-cluster # topology тест, ~15-20 мин
|
||||
|
||||
# ─── Аддоны (Helm lint + template rendering) ───────────────────────────────
|
||||
make molecule-addon-technitium-dns # ~2-3 мин
|
||||
make molecule-addon-authelia # ~2-3 мин
|
||||
make molecule-addon-ingress-proxypass # ~2 мин
|
||||
make molecule-addon-ingress-add-domains # ~2 мин
|
||||
make molecule-addon-yandex-dns-controller # ~2 мин
|
||||
|
||||
# ─── Группы ────────────────────────────────────────────────────────────────
|
||||
make molecule-addon-all # все аддоны последовательно, ~15 мин
|
||||
make molecule-all # всё: роли + аддоны + HTML отчёт, ~40 мин
|
||||
|
||||
# ─── Отчёт и линтинг ───────────────────────────────────────────────────────
|
||||
make molecule-report # генерировать HTML из /tmp/molecule-junit/*.xml
|
||||
make molecule-lint # yamllint + ansible-lint в контейнере
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## HTML отчёт
|
||||
|
||||
После каждого запуска `make molecule-all` автоматически генерируется HTML отчёт. Для ручного запуска:
|
||||
|
||||
```bash
|
||||
make molecule-report
|
||||
```
|
||||
|
||||
Отчёт по умолчанию создаётся в `/tmp/molecule-report.html`. Чтобы открыть:
|
||||
|
||||
```bash
|
||||
open /tmp/molecule-report.html
|
||||
```
|
||||
|
||||
### Как работает
|
||||
|
||||
Ansible callback `junit` записывает результаты каждой задачи в XML файлы (`/tmp/molecule-junit/*.xml`). Скрипт `scripts/molecule-report.py` читает эти XML и генерирует один HTML с:
|
||||
|
||||
- Общей статистикой: Total / Passed / Failed / Skipped
|
||||
- Таблицей по каждому сценарию (Expand / Collapse)
|
||||
- Подробностями ошибок — текст failure прямо в строке задачи
|
||||
- Авто-раскрытием упавших сценариев
|
||||
|
||||
Для включения JUnit callback задай переменные окружения перед запуском:
|
||||
|
||||
```bash
|
||||
export JUNIT_OUTPUT_DIR=/tmp/molecule-junit
|
||||
export ANSIBLE_CALLBACKS_ENABLED=junit
|
||||
```
|
||||
|
||||
Команды `molecule-addon` и `molecule-cluster` в `docker/entrypoint.sh` задают их автоматически.
|
||||
|
||||
---
|
||||
|
||||
## Жизненный цикл теста
|
||||
|
||||
```
|
||||
dependency → зависимые роли
|
||||
lint → yamllint + ansible-lint
|
||||
syntax → ansible-playbook --syntax-check
|
||||
create → запустить Docker-контейнер
|
||||
prepare → подготовить контейнер (Python, collections)
|
||||
create → запустить Docker-контейнер(ы)
|
||||
prepare → подготовить контейнер
|
||||
converge → выполнить тестируемые задачи
|
||||
idempotency → повторный converge (проверка изменений = 0)
|
||||
idempotency → повторный converge (проверка: changed=0)
|
||||
verify → assertions (проверить результаты)
|
||||
destroy → удалить контейнер
|
||||
destroy → удалить контейнер(ы)
|
||||
```
|
||||
|
||||
При ошибке на любой фазе тест падает, контейнер удаляется автоматически.
|
||||
При ошибке на любой фазе тест падает, контейнеры удаляются автоматически.
|
||||
|
||||
## Что тестирует каждая роль
|
||||
---
|
||||
|
||||
## Описание тестов
|
||||
|
||||
### Роль `k3s` (3 контейнера, ~8-12 мин)
|
||||
|
||||
@@ -61,6 +118,30 @@ destroy → удалить контейнер
|
||||
| `disable: [traefik]` | все | Traefik выключен |
|
||||
| `net.ipv4.ip_forward = 1` | все | sysctl применён |
|
||||
|
||||
### Кластер (`molecule/cluster/`, ~15-20 мин)
|
||||
|
||||
Тестирует **topology HA кластера**: 3 master (embedded etcd) + 2 worker.
|
||||
|
||||
| Контейнер | Роль | Образ |
|
||||
|---|---|---|
|
||||
| `master01` | Primary master (cluster-init) | `geerlingguy/docker-ubuntu2204-ansible` (privileged) |
|
||||
| `master02` | HA master (join) | `geerlingguy/docker-ubuntu2204-ansible` (privileged) |
|
||||
| `master03` | HA master (join) | `geerlingguy/docker-ubuntu2204-ansible` (privileged) |
|
||||
| `worker01` | Worker | `geerlingguy/docker-ubuntu2204-ansible` |
|
||||
| `worker02` | Worker | `geerlingguy/docker-ubuntu2204-ansible` |
|
||||
|
||||
Что проверяет `verify.yml`:
|
||||
|
||||
| Проверка | Нода | Что именно |
|
||||
|---|---|---|
|
||||
| `cluster-init: true` | master01 | Только первый мастер инициализирует |
|
||||
| нет ключа `server:` | master01 | Первый мастер не join-ит |
|
||||
| `server: https://192.168.1.100:6443` | master02, master03 | Join через kube-vip VIP |
|
||||
| нет `cluster-init` | master02, master03 | Не инициализируют заново |
|
||||
| `server: https://192.168.1.100:6443` | worker01, worker02 | Подключаются через VIP |
|
||||
| kube-vip DaemonSet manifest | все master | Файл `/var/lib/rancher/k3s/server/manifests/kube-vip.yaml` |
|
||||
| VIP `192.168.1.100` | kube-vip manifest | Правильный IP в аннотации |
|
||||
|
||||
### Роль `prometheus-stack` (~2-3 мин)
|
||||
|
||||
Тестирует рендеринг Jinja2-шаблона без privileged режима.
|
||||
@@ -84,6 +165,75 @@ destroy → удалить контейнер
|
||||
| `peer-authentication.yaml` | `kind: PeerAuthentication`, `spec.mtls.mode: STRICT` |
|
||||
| `kiali-token-secret.yaml` | `type: kubernetes.io/service-account-token` |
|
||||
|
||||
### Аддон `technitium-dns` (~2-3 мин)
|
||||
|
||||
Helm lint + `helm template` → assertions по Kubernetes манифестам.
|
||||
|
||||
| Проверка | Что именно |
|
||||
|---|---|
|
||||
| `primary.ip == 192.168.1.53` | values.yaml.j2 рендер |
|
||||
| `secondary.enabled == true` | secondary DNS включён |
|
||||
| `dns.forwarders` содержит `1.1.1.1`, `8.8.8.8` | форвардеры |
|
||||
| `sync.schedule == '*/5 * * * *'` | расписание синхронизации |
|
||||
| `kind: Deployment` (primary + secondary) | оба Deployment рендерятся |
|
||||
| `kind: CronJob` | CronJob синхронизации зон |
|
||||
| `def main` в ConfigMap | sync.py вложен |
|
||||
| `kube-vip.io/loadbalancerIPs` | аннотация kube-vip |
|
||||
| `LoadBalancer` | тип Service |
|
||||
| `port: 53` | DNS порт |
|
||||
|
||||
### Аддон `authelia` (~2-3 мин)
|
||||
|
||||
| Проверка | Что именно |
|
||||
|---|---|
|
||||
| `v.oidc.enabled == true` | OIDC включён |
|
||||
| Gitea/Grafana clients `enabled: true` | OIDC клиенты |
|
||||
| `protectedDomains` содержит sonarr, radarr | access control |
|
||||
| `oidcDomains` содержит gitea, grafana | bypass для OIDC |
|
||||
| `adminDomains` содержит argocd, vault | admin-only домены |
|
||||
| `kind: Deployment` | Authelia Deployment |
|
||||
| `configuration.yml` в Secret | конфиг смонтирован |
|
||||
| `identity_providers` в манифесте | OIDC секция рендерится |
|
||||
| `AUTHELIA_JWT_SECRET_FILE` | env var из Secret |
|
||||
| `authelia.authelia.svc.cluster.local` | URL forward-auth |
|
||||
|
||||
### Аддон `ingress-proxypass` (~2 мин)
|
||||
|
||||
| Проверка | Что именно |
|
||||
|---|---|
|
||||
| `defaults.ingressClass == nginx` | значение по умолчанию |
|
||||
| 2 proxy записи | plex + router |
|
||||
| `plex.home.local` в Ingress | хост plex |
|
||||
| `router` auth `enabled: true` | basic auth включён |
|
||||
| `kind: Service`, `kind: Endpoints` | созданы для каждого proxy |
|
||||
| `kind: Secret` | htpasswd Secret для router |
|
||||
| `proxy-connect-timeout` аннотация | timeout аннотации |
|
||||
|
||||
### Аддон `ingress-add-domains` (~2 мин)
|
||||
|
||||
| Проверка | Что именно |
|
||||
|---|---|
|
||||
| 2 entry записи | gitea + grafana |
|
||||
| `gitea.home.local` в Ingress | хост gitea |
|
||||
| `namespace: gitea` | Ingress в namespace сервиса |
|
||||
| `gitea-http` в backend | правильное имя Service |
|
||||
| `kind: Secret` | htpasswd Secret для grafana |
|
||||
| `auth-type` аннотация | basic auth аннотация |
|
||||
|
||||
### Аддон `yandex-dns-controller` (~2 мин)
|
||||
|
||||
| Проверка | Что именно |
|
||||
|---|---|
|
||||
| `controller.schedule == '*/5 * * * *'` | расписание |
|
||||
| `secret.orgId`, `secret.token` | API credentials |
|
||||
| `zones.domains[0].name == home.local` | конфигурация зоны |
|
||||
| `kind: CronJob` | CronJob рендерится |
|
||||
| `def main` в ConfigMap | controller.py вложен |
|
||||
| `kind: Secret` | API credentials в Secret |
|
||||
| `kind: ServiceAccount`, `kind: Role` | RBAC |
|
||||
|
||||
---
|
||||
|
||||
## Запуск тестов пошагово
|
||||
|
||||
### Линтинг (~30 сек)
|
||||
@@ -92,7 +242,7 @@ destroy → удалить контейнер
|
||||
make molecule-lint
|
||||
```
|
||||
|
||||
Запускает `yamllint .` и `ansible-lint` на всём проекте. Используй перед каждым коммитом.
|
||||
Запускает `yamllint .` и `ansible-lint` на всём проекте.
|
||||
|
||||
### Тест одной роли
|
||||
|
||||
@@ -105,20 +255,7 @@ make molecule-k3s
|
||||
INFO Running default > create
|
||||
TASK [Create instance(s)] ****
|
||||
changed: [localhost] => (item=master01)
|
||||
changed: [localhost] => (item=worker01)
|
||||
changed: [localhost] => (item=rpi01)
|
||||
|
||||
INFO Running default > converge
|
||||
TASK [Test server config template rendering] ***
|
||||
changed: [master01]
|
||||
|
||||
INFO Running default > idempotency
|
||||
PLAY RECAP
|
||||
master01 : ok=12 changed=0 unreachable=0 failed=0
|
||||
worker01 : ok=12 changed=0 unreachable=0 failed=0
|
||||
rpi01 : ok=12 changed=0 unreachable=0 failed=0
|
||||
|
||||
INFO Idempotency completed successfully.
|
||||
...
|
||||
|
||||
INFO Running default > verify
|
||||
TASK [Assert cluster-init is set (только master01)] ***
|
||||
@@ -128,6 +265,30 @@ INFO Running default > destroy
|
||||
✓ k3s role: OK
|
||||
```
|
||||
|
||||
### Тест кластера (3 master + 2 worker)
|
||||
|
||||
```bash
|
||||
make molecule-cluster
|
||||
```
|
||||
|
||||
### Тест аддона
|
||||
|
||||
```bash
|
||||
make molecule-addon-authelia
|
||||
```
|
||||
|
||||
Аддон-тесты используют `delegate_to: localhost` для `helm lint` и `helm template` — команды выполняются прямо в runner-контейнере (где есть Helm), результат сохраняется в тестовый контейнер.
|
||||
|
||||
### Все тесты + HTML отчёт
|
||||
|
||||
```bash
|
||||
make molecule-all
|
||||
```
|
||||
|
||||
Запускает все сценарии последовательно и генерирует `open /tmp/molecule-report.html`.
|
||||
|
||||
---
|
||||
|
||||
## Отладка упавших тестов
|
||||
|
||||
```bash
|
||||
@@ -138,84 +299,130 @@ docker run --rm -it \
|
||||
--entrypoint bash \
|
||||
k3s-ansible
|
||||
|
||||
# Внутри — перейти к нужной роли:
|
||||
cd /ansible/roles/k3s # или roles/prometheus-stack / addons/jenkins/role
|
||||
# Роль:
|
||||
cd /ansible/roles/k3s
|
||||
molecule converge
|
||||
molecule login
|
||||
molecule login --host master01
|
||||
molecule verify
|
||||
molecule converge -- -vvv
|
||||
molecule destroy
|
||||
|
||||
# Запускать фазы вручную:
|
||||
molecule converge # создать контейнер и запустить задачи
|
||||
molecule login # войти в тестовый контейнер
|
||||
molecule login --host master01 # конкретная нода
|
||||
molecule verify # только assertions
|
||||
molecule converge -- -vvv # подробный вывод
|
||||
molecule destroy # удалить тестовые контейнеры
|
||||
# Аддон:
|
||||
cd /ansible/addons/authelia/role
|
||||
molecule converge
|
||||
molecule login
|
||||
molecule verify
|
||||
|
||||
# Отдельные фазы:
|
||||
molecule lint
|
||||
molecule syntax
|
||||
molecule create
|
||||
molecule prepare
|
||||
molecule idempotency
|
||||
# Кластер:
|
||||
cd /ansible
|
||||
molecule test -s cluster
|
||||
molecule converge -s cluster
|
||||
molecule verify -s cluster
|
||||
molecule destroy -s cluster
|
||||
```
|
||||
|
||||
## Написание новых тестов
|
||||
---
|
||||
|
||||
### molecule.yml
|
||||
## Написание новых тестов для аддонов
|
||||
|
||||
### molecule.yml (шаблон)
|
||||
|
||||
```yaml
|
||||
driver:
|
||||
name: docker
|
||||
platforms:
|
||||
- name: my-test-instance
|
||||
- name: master01
|
||||
image: geerlingguy/docker-ubuntu2204-ansible:latest
|
||||
pre_build_image: true
|
||||
privileged: true # нужно для sysctl, модулей ядра
|
||||
groups:
|
||||
- k3s_master
|
||||
provisioner:
|
||||
name: ansible
|
||||
playbooks:
|
||||
converge: converge.yml
|
||||
verify: verify.yml
|
||||
config_options:
|
||||
defaults:
|
||||
interpreter_python: auto_silent
|
||||
verifier:
|
||||
name: ansible
|
||||
```
|
||||
|
||||
### converge.yml
|
||||
### converge.yml (шаблон для аддона с Helm chart)
|
||||
|
||||
```yaml
|
||||
- name: Converge
|
||||
- name: Converge — my-addon template tests
|
||||
hosts: all
|
||||
become: true
|
||||
become: false
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
kube_vip_address: "192.168.1.100" # все нужные переменные здесь
|
||||
k3s_version: "v1.29.3+k3s1"
|
||||
my_addon_namespace: my-addon
|
||||
# ... все переменные аддона ...
|
||||
|
||||
tasks:
|
||||
- name: Render template
|
||||
- name: Render Helm values
|
||||
ansible.builtin.template:
|
||||
src: "{{ playbook_dir }}/../../templates/my-template.j2"
|
||||
dest: /tmp/result.yaml
|
||||
src: "{{ playbook_dir }}/../../templates/values.yaml.j2"
|
||||
dest: /tmp/my-addon-values.yaml
|
||||
mode: "0644"
|
||||
|
||||
- name: Run helm lint
|
||||
ansible.builtin.command: >
|
||||
helm lint /ansible/addons/my-addon/role/chart
|
||||
--values /tmp/my-addon-values.yaml --strict
|
||||
delegate_to: localhost
|
||||
changed_when: false
|
||||
|
||||
- name: Run helm template
|
||||
ansible.builtin.command: >
|
||||
helm template my-addon /ansible/addons/my-addon/role/chart
|
||||
--values /tmp/my-addon-values.yaml --namespace my-addon
|
||||
delegate_to: localhost
|
||||
changed_when: false
|
||||
register: helm_template_result
|
||||
|
||||
- name: Save manifests
|
||||
ansible.builtin.copy:
|
||||
content: "{{ helm_template_result.stdout }}"
|
||||
dest: /tmp/my-addon-manifests.yaml
|
||||
mode: "0644"
|
||||
```
|
||||
|
||||
### verify.yml
|
||||
### verify.yml (шаблон)
|
||||
|
||||
```yaml
|
||||
- name: Verify
|
||||
- name: Verify — my-addon templates
|
||||
hosts: all
|
||||
tasks:
|
||||
- name: Read result
|
||||
- name: Read values
|
||||
ansible.builtin.slurp:
|
||||
src: /tmp/result.yaml
|
||||
register: raw
|
||||
src: /tmp/my-addon-values.yaml
|
||||
register: values_raw
|
||||
|
||||
- name: Parse YAML
|
||||
- name: Parse values
|
||||
ansible.builtin.set_fact:
|
||||
result: "{{ raw.content | b64decode | from_yaml }}"
|
||||
v: "{{ values_raw.content | b64decode | from_yaml }}"
|
||||
|
||||
- name: Assert key exists
|
||||
- name: Assert key value
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- result.myKey == 'expected-value'
|
||||
- result.enabled == true
|
||||
fail_msg: "Ожидалось 'expected-value', получено: {{ result.myKey }}"
|
||||
that: v.myKey == 'expected'
|
||||
fail_msg: "myKey неверный: {{ v.myKey }}"
|
||||
|
||||
- name: Read manifests
|
||||
ansible.builtin.slurp:
|
||||
src: /tmp/my-addon-manifests.yaml
|
||||
register: manifests_raw
|
||||
|
||||
- name: Assert Deployment rendered
|
||||
ansible.builtin.assert:
|
||||
that: "'kind: Deployment' in (manifests_raw.content | b64decode)"
|
||||
fail_msg: "Deployment не найден"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Типичные ошибки
|
||||
|
||||
| Ошибка | Причина | Решение |
|
||||
@@ -226,3 +433,6 @@ verifier:
|
||||
| `yamllint: wrong indentation` | Ошибка отступа | Исправь файл, `make molecule-lint` |
|
||||
| `ansible-lint: no-changed-when` | shell/command без changed_when | Добавь `changed_when: <условие>` |
|
||||
| `sysctl: Operation not permitted` | Нет privileged | Добавь `privileged: true` в molecule.yml |
|
||||
| `helm: command not found` | helm в тестовом контейнере | Используй `delegate_to: localhost` для helm команд |
|
||||
| JUnit XML не создаётся | Callback не активирован | Задай `ANSIBLE_CALLBACKS_ENABLED=junit` и `JUNIT_OUTPUT_DIR` |
|
||||
| HTML отчёт пустой | XML файлов нет | Убедись что тесты запускались через `make molecule-*` |
|
||||
|
||||
Reference in New Issue
Block a user