diff --git a/gestion/config/trigger.py b/gestion/config/trigger.py index 564ebe30..1763135a 100644 --- a/gestion/config/trigger.py +++ b/gestion/config/trigger.py @@ -15,7 +15,7 @@ services = { 'dhcp' : ["dhcp"], 'dyson' : ["autostatus"], 'isc' : ["dhcp"], - 'komaz' : ["mac_ip", "secours"], + 'komaz' : ["firewall", "secours"], 'owl' : ["userdel"], 'redisdead' : ["mailman", "modif_ldap", "solde", "userdel", "secours"], 'sable' : ["dns"], diff --git a/gestion/trigger/firewall4 b/gestion/trigger/firewall4 new file mode 120000 index 00000000..7aeba490 --- /dev/null +++ b/gestion/trigger/firewall4 @@ -0,0 +1 @@ +../gen_confs/firewall4 \ No newline at end of file diff --git a/gestion/trigger/services/event.py b/gestion/trigger/services/event.py index 7e8fd5a0..e4fa935b 100644 --- a/gestion/trigger/services/event.py +++ b/gestion/trigger/services/event.py @@ -15,7 +15,7 @@ import cranslib.clogger as clogger import pika import lc_ldap.attributs -logger = clogger.CLogger("trigger", "info") +logger = clogger.CLogger("trigger.event", "info") class Event(cmb.BasicProducer): """ @@ -128,6 +128,8 @@ def event(body=()): """ + logger.info("Received message %s…", body) + diff = diff_o_matic(body) # À cette étape, on a un dico des attrs ayant subi une modif @@ -140,6 +142,7 @@ def event(body=()): # Si la mac ou l'IP a changé… if diff.has_key(lc_ldap.attributs.ipHostNumber.ldap_name) or diff.has_key(lc_ldap.attributs.macAddress.ldap_name): + logger.info("Detected MAC or IP update, calling trigger_mac_ip…", body) trigger_mac_ip(body, diff) def trigger_mac_ip(body, diff): @@ -150,17 +153,18 @@ def trigger_mac_ip(body, diff): # Régénération du DHCP : if not macs[0]: # Création d'une nouvelle machine. - to_send = {'add': (macs[1], ips[1], hostnames[1])} + dhcp = {'add': (macs[1], ips[1], hostnames[1])} + fw = {'add': (macs[1], ips[1])} elif not macs[1]: # Destruction d'une machine. to_send = {'delete': (macs[0], ips[0])} + fw = {'delete': (macs[0], ips[0])} else: # Mise à jour. to_send = {'update': (macs[0], ips[0], macs[1], ips[1], hostnames[1])} + fw = {'update': (macs[0], ips[0], macs[1], ips[1])} trigger_send('dhcp', to_send) - - # Régénération du parefeu. - trigger_send('mac_ip', to_send) + trigger_send('firewall_mac_ip', fw) def trigger_send(ttype, to_send): print "Sending trigger %s with %s…" % (ttype, to_send) diff --git a/gestion/trigger/services/firewall.py b/gestion/trigger/services/firewall.py new file mode 100644 index 00000000..983f0f26 --- /dev/null +++ b/gestion/trigger/services/firewall.py @@ -0,0 +1,150 @@ +#!/bin/bash /usr/scripts/python.sh +# -*- coding: utf-8 -*- +# +# Service in charge of firewall for trigger. +# +# Author : Pierre-Elliott Bécue +# Licence : GPLv3 + +import lc_ldap.shortcuts +from gestion.trigger.host import record +import cranslib.clogger as clogger +import gestion.config.dhcp as dhcp_config +import gestion.secrets_new as secrets_new +import socket +import gestion.affichage as affichage +import os +import sys +import gestion.iptools as iptools + +logger = clogger.CLogger("trigger.firewall", "debug") +hostname = socket.gethostname().split(".")[0] + ".adm.crans.org" +dhcp_omapi_keyname = secrets_new.get("dhcp_omapi_keyname") +dhcp_omapi_key = secrets_new.get("dhcp_omapi_keys")[hostname] +ldap_conn = lc_ldap.shortcuts.lc_ldap_readonly() + +def add_dhcp_host(mac, ip, name=None): + """Adds a dhcp host using omapi + + """ + + if '' in [ip, mac]: + return + msg = OmapiMessage.open(b"host") + msg.message.append((b"create", struct.pack("!I", 1))) + msg.message.append((b"exclusive", struct.pack("!I", 1))) + msg.obj.append((b"hardware-address", pack_mac(mac))) + msg.obj.append((b"hardware-type", struct.pack("!I", 1))) + msg.obj.append((b"ip-address", pack_ip(ip))) + if name: + msg.obj.append((b"name", bytes(name))) + conn = Omapi(hostname, 9991, dhcp_omapi_keyname, dhcp_omapi_key) + response = conn.query_server(msg) + conn.close() + +def delete_dhcp_host(self, mac, ip): + """Deletes dhcp host using omapi + + """ + + if '' in [ip, mac]: + return + msg = OmapiMessage.open(b"host") + msg.obj.append((b"hardware-address", pack_mac(mac))) + msg.obj.append((b"hardware-type", struct.pack("!I", 1))) + msg.obj.append((b"ip-address", pack_ip(ip))) + conn = Omapi(hostname, 9991, dhcp_omapi_keyname, dhcp_omapi_key) + response = conn.query_server(msg) + if response.opcode == OMAPI_OP_UPDATE: + response = conn.query_server(OmapiMessage.delete(response.handle)) + conn.close() + +def lease_clean(): + """Clean the lease file + + """ + # TODO : use ConfigFile structure + leasefile = open(dhcp_config.dhcplease) + newleasefile = open(dhcp_config.dhcplease + '.new', 'w') + config = "" + line = leasefile.readline() + write = True + while line: + if line.strip().startswith('host'): + write = False + if write: + newleasefile.write(line) + if not write and line.strip().endswith('}'): + write = True + line = leasefile.readline() + leasefile.close() + newleasefile.close() + os.rename(dhcp_config.dhcplease+'.new', dhcp_config.dhcplease) + +@record +def dhcp(body={}): + """Regenerates dhcp service taking body into account. + + """ + if body and isinstance(body, dict): + for (mac, ip, name) in body.get("add", ()): + add_dhcp_host(mac, ip, name) + for (mac, ip) in body.get("delete", ()): + delete_dhcp_host(mac, ip) + for (rmac, rip, mac, ip, name) in body.get("update", ()): + delete_dhcp_host(rmac, rip) + add_dhcp_host(mac, ip, name) + elif body == True: + hosts = {} + host_template = """ + host %(nom)s { + hardware ethernet %(mac)s; + fixed-address %(ip)s; + option host-name "%(host)s"; + } +""" + affichage.prettyDoin("Chargement des machines", "...") + machines = ldap_conn.allMachines() + affichage.prettyDoin("Chargement des machines", "Ok") + animation = affichage.Animation(texte="Génération de la configuration", + nb_cycles=len(machines), + couleur=True, + kikoo=True) + + for machine in machines: + for net in dhcp_config.reseaux.keys(): + ip = str(machine['ipHostNumber'][0]) + mac = str(machine['macAddress'][0]) + nom = str(machine['host'][0]) + if '' not in [ip, mac] and iptools.AddrInNet(ip, net): + d = {'nom' : nom, + 'host' : nom.split(".", 1)[0], + 'mac' : mac, + 'ip' : ip, + } + try: + hosts[net] += host_template % d + except: + hosts[net] = host_template % d + animation.new_step() + # Put a \n after the last iteration. + animation.end() + + step = "Enregistrement de la configuration dans les fichiers" + affichage.prettyDoin(step, "...") + for (net, fichier) in dhcp_config.reseaux.items(): + with ConfFile(fichier) as configFile: + configFile.header("#") + if hosts.has_key(net): + configFile.write(hosts[net]) + affichage.prettyDoin(step, "Ok") + + step = "Nettoyage des fichiers de leases" + affichage.prettyDoin(step, "...") + try: + lease_clean() + affichage.prettyDoin(step, "Ok") + except: + affichage.prettyDoin(step, "Erreur") + print "During lease clean, an error occured." + raise