From fe3df776db356807b304355889f22d40bb254de3 Mon Sep 17 00:00:00 2001
From: Alexandre Iooss <erdnaxe@crans.org>
Date: Sun, 26 Apr 2020 18:18:18 +0200
Subject: [PATCH] Use Re2o API to config Bind9

---
 README.md                                     |  8 ++++-
 network.yml                                   |  7 ++--
 .../templates/bind/named.conf.local.j2        | 35 ++++++++++++++-----
 3 files changed, 36 insertions(+), 14 deletions(-)

diff --git a/README.md b/README.md
index 5fc17d39..3bf6f1a3 100644
--- a/README.md
+++ b/README.md
@@ -80,6 +80,12 @@ on peut exécuter le module `setup` manuellement.
 ansible zamok.adm.crans.org -m setup
 ```
 
+### Filtrer un objet Python
+
+Ansible fournit le filtre `json_query` qui va utiliser
+le module python `jmespath`. Il est puissant et permet entre autre
+de filtrer la sortie de l'API Re2o.
+
 ## Exécution d'Ansible
 
 ### Configurer la connexion au vlan adm
@@ -103,7 +109,7 @@ ssh-copy-id zamok.adm.crans.org
 
 ### Lancer un Playbook Ansible
 
-Il faut `python3-netaddr` sur sa machine.
+Il faut `python3-netaddr` et `python3-jmespath` sur sa machine.
 
 Pour tester le playbook `base.yml` :
 ```bash
diff --git a/network.yml b/network.yml
index f3f8c589..cca663b0 100755
--- a/network.yml
+++ b/network.yml
@@ -41,10 +41,9 @@
   vars:
     certbot_dns_secret: "{{ vault_certbot_dns_secret }}"
     bind:
-      master: false
-      master_ip: 10.231.136.118
-      slaves: []  # TODO
-      zones: "{{ lookup('re2oapi', 'dnszones', api_hostname='intranet.crans.org') }}"
+      masters: "{{ lookup('re2oapi', 'get_role', 'dns-authoritary-master')[0] }}"
+      slaves: "{{ lookup('re2oapi', 'get_role', 'dns-authoritary-slave')[0] }}"
+      zones: "{{ lookup('re2oapi', 'dnszones') }}"
   roles:
     - bind-authoritative
 
diff --git a/roles/bind-authoritative/templates/bind/named.conf.local.j2 b/roles/bind-authoritative/templates/bind/named.conf.local.j2
index c84b3356..b5c3fbcb 100644
--- a/roles/bind-authoritative/templates/bind/named.conf.local.j2
+++ b/roles/bind-authoritative/templates/bind/named.conf.local.j2
@@ -4,29 +4,41 @@
 // organization
 //include "/etc/bind/zones.rfc1918";
 
-{% if bind.master %}
+{%- set masters_ipv4 = bind.masters | json_query("servers[].interface[?vlan_id==`2`].ipv4[]") %}
+{%- set masters_ipv6 = bind.masters | json_query("servers[].interface[?vlan_id==`2`].ipv6[][].ipv6") %}
+{%- set slaves_ipv4 = bind.slaves | json_query("servers[].interface[?vlan_id==`2`].ipv4[]") %}
+{%- set slaves_ipv6 = bind.slaves | json_query("servers[].interface[?vlan_id==`2`].ipv6[][].ipv6") %}
+{%- set is_master = ansible_all_ipv4_addresses | intersect(masters_ipv4) %}
+
+{% if is_master -%}
 // Let's Encrypt Challenge DNS-01
 key "certbot_challenge." {
-    algorithm hmac-sha512;
-    secret "{{ certbot_dns_secret }}";
+	algorithm hmac-sha512;
+	secret "{{ certbot_dns_secret }}";
 };
 {% endif %}
 
 // Crans zones
 {% for zone in bind.zones %}
 zone "{{ zone }}" {
-	{% if bind.master -%}
+	{% if is_master -%}
 	type master;
 	file "/var/local/re2o-services/dns/generated/dns.{{ zone }}.zone";
 	forwarders {
-		{% for slave in bind.slaves -%}
-		{{ slave }};
+		{% for ip in slaves_ipv4 -%}
+		{{ ip }};
 		{% endfor -%}
+		{% for ip in slaves_ipv6 -%}
+		{{ ip }};
+	{% endfor -%}
 	};
 	allow-transfer {
-		{% for slave in bind.slaves -%}
-		{{ slave }};
+		{% for ip in slaves_ipv4 -%}
+		{{ ip }};
 		{% endfor -%}
+		{% for ip in slaves_ipv6 -%}
+		{{ ip }};
+	{% endfor -%}
 	};
 	update-policy {
 		grant certbot_challenge. name _acme-challenge.{{ zone }} txt;
@@ -36,7 +48,12 @@ zone "{{ zone }}" {
 	type slave;
 	file "bak.{{ zone }}";
 	masters {
-		{{ bind.master_ip }};
+		{% for ip in masters_ipv4 -%}
+		{{ ip }};
+		{% endfor -%}
+		{% for ip in masters_ipv6 -%}
+		{{ ip }};
+	{% endfor -%}
 	};
 	allow-transfer { "none"; };
 	notify no;
-- 
GitLab