From b3ec02046dc5a24f598f0b15f79cc5659418c8d0 Mon Sep 17 00:00:00 2001
From: Evangelos Foutras <evangelos@foutrelis.com>
Date: Wed, 27 Apr 2022 19:22:56 +0300
Subject: [PATCH] geomirror: leverage LUA records for failover+GeoIP

PowerDNS provides a neat way to implement GeoIP-based redirection and
automatic failover. With GeoLite2-City database, it is able to select
the closest mirror from a list of IPs we provide. Every 60 seconds it
also checks if the mirror's HTTPS URL is working as expected; if that
check fails, it stops giving it out (this acts as automatic failover).
---
 roles/geomirror/meta/main.yml          |  2 ++
 roles/geomirror/templates/geo.yml.j2   | 29 +++++++++++---------------
 roles/geomirror/templates/pdns.conf.j2 |  4 +++-
 3 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/roles/geomirror/meta/main.yml b/roles/geomirror/meta/main.yml
index 45b670ef2..d21409a9b 100644
--- a/roles/geomirror/meta/main.yml
+++ b/roles/geomirror/meta/main.yml
@@ -1,3 +1,5 @@
 ---
 dependencies:
   - role: geoipupdate
+    vars:
+      geoipupdate_edition_ids: GeoLite2-City
diff --git a/roles/geomirror/templates/geo.yml.j2 b/roles/geomirror/templates/geo.yml.j2
index 581749187..f9310c250 100644
--- a/roles/geomirror/templates/geo.yml.j2
+++ b/roles/geomirror/templates/geo.yml.j2
@@ -10,24 +10,19 @@ domains:
       {% for host in groups['geo_mirrors'] %}
         - ns: {{ host }}
       {% endfor %}
-      {% for host in groups['geo_mirrors'] %}
-      {{ host.split(".")[0] }}.{{ geo_mirror_domain }}:
-        - a: {{ hostvars[host]['ipv4_address'] }}
-        - aaaa: {{ hostvars[host]['ipv6_address'] }}
-      {% endfor %}
+        - lua:
+            ttl: 300
+            content: >
+              A "ifurlup('https://{{ geo_mirror_domain }}/lastupdate',
+              {'{{ groups['geo_mirrors'] | map('extract', hostvars, ['ipv4_address']) | join("', '") }}'},
+              {selector='pickclosest', useragent='pdns on {{ inventory_hostname }}'})"
+        - lua:
+            ttl: 300
+            content: >
+              AAAA "ifurlup('https://{{ geo_mirror_domain }}/lastupdate',
+              {'{{ groups['geo_mirrors'] | map('extract', hostvars, ['ipv6_address']) | join("', '") }}'},
+              {selector='pickclosest', useragent='pdns on {{ inventory_hostname }}'})"
       {% if not geomirror_acme_challenge %}
       _acme-challenge.{{ geo_mirror_domain }}:
         - ns: mirror.pkgbuild.com
       {% endif %}
-    services:
-      {{ geo_mirror_domain }}: '%mp.geo.mirror.pkgbuild.com'
-mapping_lookup_formats: ['%cn']
-custom_mapping:
-  af: europe
-  an: europe
-  as: asia
-  eu: europe
-  na: america
-  oc: asia
-  sa: america
-  unknown: europe
diff --git a/roles/geomirror/templates/pdns.conf.j2 b/roles/geomirror/templates/pdns.conf.j2
index 8a9c1fbd9..6539ab25d 100644
--- a/roles/geomirror/templates/pdns.conf.j2
+++ b/roles/geomirror/templates/pdns.conf.j2
@@ -12,5 +12,7 @@ lua-dnsupdate-policy-script=/etc/powerdns/dnsupdate-policy.lua
 {% else %}
 launch=geoip
 {% endif %}
-geoip-database-files=/var/lib/GeoIP/GeoLite2-Country.mmdb
+geoip-database-files=/var/lib/GeoIP/GeoLite2-City.mmdb
 geoip-zones-file=/etc/powerdns/geo.yml
+enable-lua-records
+lua-health-checks-interval=60
-- 
GitLab