L edge expose les interfaces web aux personnes ; les VM du site vont directement au service. Declare par domaine (service | edge, defaut edge) ; plancher, zone et certificat du service suivent. Pose au site : 35 planchers sur 35 conformes ; locataires inchanges. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
83 lines
4.5 KiB
Django/Jinja
83 lines
4.5 KiB
Django/Jinja
$ORIGIN {{ serveur_powerdns_zone }}.
|
|
$TTL {{ serveur_powerdns_ttl }}
|
|
@ IN SOA {{ serveur_powerdns_nameserver }}.{{ serveur_powerdns_zone }}. {{ serveur_powerdns_contact }}. (
|
|
{{ serveur_powerdns_serial }}
|
|
{{ serveur_powerdns_soa_refresh }}
|
|
{{ serveur_powerdns_soa_retry }}
|
|
{{ serveur_powerdns_soa_expire }}
|
|
{{ serveur_powerdns_soa_minimum }}
|
|
)
|
|
|
|
@ IN NS {{ serveur_powerdns_nameserver }}.{{ serveur_powerdns_zone }}.
|
|
{{ serveur_powerdns_nameserver }} IN A {{ hostvars[groups['serveur_powerdns'][0]].ansible_host | default('127.0.0.1') }}
|
|
|
|
{# LE PLAN L'EMPORTE SUR LE DEFAUT DU ROLE (2026-08-25).
|
|
|
|
`serveur_powerdns_records` porte un defaut de commodite : `dns IN CNAME ns1`. Le plan
|
|
du site, lui, expose `dns.genese.internal` pour `serveur_resolveur` — ce qui produit un
|
|
`dns IN A`. Un nom ne peut pas porter a la fois un CNAME et un A : `named-checkzone` a
|
|
refuse la zone (« CNAME and other data »), et PowerDNS ne l'a pas servie du tout.
|
|
|
|
La garde a bien fonctionne — elle a arrete une zone cassee avant qu'elle soit servie.
|
|
Mais elle laissait le DNS du site sans zone tant que la collision durait.
|
|
|
|
On ecarte donc le record statique quand le plan expose le meme nom. C'est le sens de
|
|
marche du depot : ce qui est DECLARE AU PLAN prime sur ce qu'un role suppose par
|
|
defaut. Les deux pointaient de toute facon vers la meme machine. #}
|
|
{% set _exposes = [] %}
|
|
{% if serveur_powerdns_publier_expositions | default(false) %}
|
|
{% for expo in serveur_powerdns_expositions | default([]) if expo.domaine == serveur_powerdns_zone %}
|
|
{% set _ = _exposes.append(expo.fqdn[:-(serveur_powerdns_zone | length + 1)]) %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% for record in serveur_powerdns_records if record.name not in _exposes %}
|
|
{{ record.name }} IN {{ record.type }} {{ record.value }}
|
|
{% endfor %}
|
|
|
|
{% set emitted = [] %}
|
|
{% for group_name in serveur_powerdns_inventory_groups %}
|
|
{% for host_name in groups.get(group_name, []) | sort %}
|
|
{% if hostvars[host_name].ansible_host is defined and host_name not in emitted %}
|
|
{{ host_name }} IN A {{ hostvars[host_name].ansible_host }}
|
|
{% set _ = emitted.append(host_name) %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
|
|
{% if serveur_powerdns_publier_expositions | default(false) %}
|
|
{% for expo in serveur_powerdns_expositions | default([]) if expo.domaine == serveur_powerdns_zone %}
|
|
{% set cibles = [expo.hote] if expo.resout_vers | default('edge') == 'service' else groups.get(expo.edge, []) %}
|
|
{% if cibles and cibles[0] in hostvars and hostvars[cibles[0]].ansible_host is defined %}
|
|
{{ expo.fqdn[:-(serveur_powerdns_zone | length + 1)] }} IN A {{ hostvars[cibles[0]].ansible_host }}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
|
|
{# L'EMPREINTE DU PLANCHER (2026-09-29). Le plancher `/etc/hosts` de chaque machine et
|
|
cette zone derivent du meme plan, mais pas au meme moment : chacun suit le plan quand son
|
|
role est rejoue. Le 2026-09-29, la console manquait aux planchers des deux locataires
|
|
pendant que la zone la portait. Pour que chaque machine puisse comparer SANS transfert de
|
|
zone (AXFR reste ferme), la zone publie ce que le plancher DOIT contenir pour ce domaine :
|
|
le nombre de paires « nom adresse » et leur empreinte sha256.
|
|
|
|
LE MEME ENSEMBLE QUE `hosts_statiques/templates/hosts.j2`, pas celui de cette zone : la
|
|
flotte ACTIVE ET PLANIFIEE (le plancher resout un clone avant qu'il soit actif ; la zone
|
|
non), plus les expositions de ce domaine. `test_empreinte_plancher.py` rend les deux
|
|
gabarits sur un meme inventaire et exige la meme empreinte : si l'un change seul, le
|
|
test le dit. La sonde `plancher` (role `client_sante`) calcule le cote machine. #}
|
|
{% set _plancher = [] %}
|
|
{% for h in (groups.get('hotes_actifs', []) + groups.get('hotes_planifies', [])) | unique | sort %}
|
|
{% if hostvars[h].ansible_host is defined %}
|
|
{% set _ = _plancher.append(h ~ '.' ~ serveur_powerdns_zone ~ ' ' ~ hostvars[h].ansible_host) %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% if serveur_powerdns_publier_expositions | default(false) %}
|
|
{% for expo in serveur_powerdns_expositions | default([]) if expo.domaine == serveur_powerdns_zone %}
|
|
{% set cibles = [expo.hote] if expo.resout_vers | default('edge') == 'service' else groups.get(expo.edge, []) %}
|
|
{% if cibles and cibles[0] in hostvars and hostvars[cibles[0]].ansible_host is defined %}
|
|
{% set _ = _plancher.append(expo.fqdn ~ ' ' ~ hostvars[cibles[0]].ansible_host) %}
|
|
{% endif %}
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% set _paires = _plancher | unique | sort %}
|
|
_plancher IN TXT "n={{ _paires | length }} sha256={{ _paires | join('\n') | hash('sha256') }}"
|