From ea0d140a6633e4f23321c2bf423634e154f6499e Mon Sep 17 00:00:00 2001
From: shirenn <shirenn@crans.org>
Date: Fri, 7 Aug 2020 17:30:20 +0200
Subject: [PATCH] [keepalived][unsafe] PEP CRANS + dhcp notify

---
 roles/keepalived/README.md                    | 38 +++++++++++++++++++
 roles/keepalived/tasks/main.yml               | 13 +++++++
 roles/keepalived/templates/bin/notify-dhcp    | 24 ++++++++++++
 .../templates/keepalived/keepalived.conf.j2   | 36 ++++++++++--------
 4 files changed, 95 insertions(+), 16 deletions(-)
 create mode 100644 roles/keepalived/README.md
 create mode 100755 roles/keepalived/templates/bin/notify-dhcp

diff --git a/roles/keepalived/README.md b/roles/keepalived/README.md
new file mode 100644
index 00000000..884a783b
--- /dev/null
+++ b/roles/keepalived/README.md
@@ -0,0 +1,38 @@
+# KEEPALIVED
+
+Ce rôle installe keepalived pour permettre la redondance de certain service
+entre plusieurs services.
+/!\ Ce rôle déploie un script pour relancer automatiquement le serveur dhcp /!\
+
+## VARS
+
+keepalived:
+  - mail_destination: a qui envoyé les mails en cas de switching
+  - mail_source: qui envoie les mails
+  - smtp_server: le serveur smtp par qui passer pour envoyer les mails
+  - pool: Une liste de différentes instances installable sur la machine. Les
+    instances sont des dictionnaires comprenant les champs suivant :
+    - name: le nom de l'instance
+    - password: le mot de passe que vont utilisé les marchines d'une même
+      instance pour se synchroniser
+    - id: l'indentifiant qu'elles vont utiliser pour discuter
+    - ipv6: s'il est necessaire de configurer une instance supplémentaire pour
+      de l'ipv6
+    - notify: le script a notifé en cas de switching (s'il n'est pas précisé
+      aucun script n'est utilisé)
+    - administration: le vlan d'administration sur lequel les machines d'une
+      même instances vont discuter
+    - zones: une liste de zone sur lequel vont parler les instances keepalived.
+      Chaque zone est un disctionnaire comprenant les champs suivants:
+      - vlan: le vlan sur lequel est installé la zone
+      - ipv4: l'ipv4 au format CIDR partagé par les machines
+      - brd: s'il faut préciser ou non l'interface de broadcast
+      - ipv6: une ipv6 (elle peut ne pas être précisé, si elle est présente mais
+        que l'instance ne précise pas ipv6, elle sera ignoré)
+  - instances: Une liste d'instance a déployer sur la machine. Les instances
+    sont des dictionnaires comprenant les champs suivants:
+    - name: le nom de linstance a deployer
+    - tag: le petit nom à lui donner
+    - state: l'état (entre BACKUP et MASTER)
+    - priority: la priorité (pour un MASTER on met par défaut 150 puis on reduit
+      de 50 par 50)
diff --git a/roles/keepalived/tasks/main.yml b/roles/keepalived/tasks/main.yml
index 3eaa83ac..14fc00bd 100644
--- a/roles/keepalived/tasks/main.yml
+++ b/roles/keepalived/tasks/main.yml
@@ -13,3 +13,16 @@
     dest: /etc/keepalived/keepalived.conf
     mode: 0644
   notify: Reload keepalived.service
+
+- name: Create scripts directory
+  file:
+    path: /usr/scripts
+    state: directory
+
+- name: Deploy keepalived dhcp scripts
+  template:
+    src: bin/notify-dhcp
+    dest: /usr/scripts/notify-dhcp
+    mode: 0744
+  when: not ansible_check_mode
+  notify: Reload keepalived.service
diff --git a/roles/keepalived/templates/bin/notify-dhcp b/roles/keepalived/templates/bin/notify-dhcp
new file mode 100755
index 00000000..a62ad14c
--- /dev/null
+++ b/roles/keepalived/templates/bin/notify-dhcp
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+TYPE=$1
+NAME=$2
+STATE=$3
+
+case $STATE in
+	"MASTER")
+		logger -s '[DHCP-NOTIFY] Entering state MASTER, starting isc-dhcp-server.service'
+		systemctl start isc-dhcp-server.service
+		exit 0;;
+	"BACKUP")
+		logger -s '[DHCP-NOTIFY] Entering state BACKUP, stopping isc-dhcp-server.service'
+		systemctl stop isc-dhcp-server.service
+		exit 0;;
+	"FAULT")
+		logger -s '[DHCP-NOTIFY] Entering state FAULT, stopping isc-dhcp-server.service'
+		systemctl stop isc-dhcp-server.service
+		exit 0;;
+	*)
+		logger -s '[DHCP-NOTIFY] Entering UNKNOWN state, doing nothing'
+		exit 1;;
+esac
+
diff --git a/roles/keepalived/templates/keepalived/keepalived.conf.j2 b/roles/keepalived/templates/keepalived/keepalived.conf.j2
index f0530d8f..97c93c53 100644
--- a/roles/keepalived/templates/keepalived/keepalived.conf.j2
+++ b/roles/keepalived/templates/keepalived/keepalived.conf.j2
@@ -1,31 +1,33 @@
 {{ ansible_header | comment }}
 
 global_defs {
-  notification_email {
-    root@crans.org
-  }
-  notification_email_from keepalived@crans.org
-  smtp_server smtp.adm.crans.org
+  notification_email { {{ keepalived.mail_destination }} }
+  notification_email_from {{ keepalived.mail_source }}
+  smtp_server {{ keepalived.smtp_server }}
 }
 
-{% for instance in keepalived_instances %}
+{% for instance in keepalived.instances %}
 vrrp_instance {{ instance.tag }}4 {
   state {{ instance.state }}
   priority {{ instance.priority }}
   smtp_alert
 
   interface {{ interfaces.adm }}
-  virtual_router_id {{ keepalived[instance.name].id }}
+  virtual_router_id {{ keepalived.pool[instance.name].id }}
   advert_int 2
   authentication {
     auth_type PASS
-    auth_pass {{ keepalived[instance.name].password }}
+    auth_pass {{ keepalived.pool[instance.name].password }}
   }
 
+{% if keepalived.pool[instance.name].notify is defined %}
+  notify {{ keepalived.pool[instance.name].notify }}
+{% endif %}
+
   virtual_ipaddress {
-{% for zone in keepalived[instance.name].zones %}
-  {% if zone.brd is defined %}
-      {{ zone.ipv4 }} brd {{ zone.brd }} dev {{ interfaces[zone.vlan] }} scope global
+{% for zone in keepalived.pool[instance.name].zones %}
+  {% if zone.brd  %}
+      {{ zone.ipv4 }} brd {{ zone.ipv4 | ipaddr('broadcast') }} dev {{ interfaces[zone.vlan] }} scope global
   {% else %}
       {{ zone.ipv4 }} dev {{ interfaces[zone.vlan] }} scope global
   {% endif %}
@@ -33,23 +35,25 @@ vrrp_instance {{ instance.tag }}4 {
   }
 }
 
-{% if keepalived[instance.name].ipv6 %}
+{% if keepalived.pool[instance.name].ipv6 %}
 vrrp_instance {{ instance.tag }}6 {
   state {{ instance.state }}
   priority {{ instance.priority }}
   smtp_alert
 
-  interface {{ interfaces.adm }}
-  virtual_router_id {{ keepalived[instance.name].id }}
+  interface {{ keepalived.pool[instance.name].administration }}
+  virtual_router_id {{ keepalived.pool[instance.name].id }}
   advert_int 2
   authentication {
     auth_type PASS
-    auth_pass {{ keepalived[instance.name].password }}
+    auth_pass {{ keepalived.pool[instance.name].password }}
   }
 
   virtual_ipaddress {
-{% for zone in keepalived[instance.name].zones %}
+{% for zone in keepalived.pool[instance.name].zones %}
+{% if zone.ipv6 is defined %}
       {{ zone.ipv6 }} dev {{ interfaces[zone.vlan] }} scope global
+{% endif %}
 {% endfor %}
   }
 }
-- 
GitLab