#!/bin/bash /usr/scripts/python.sh # -*- coding: utf-8 -*- # # Service in charge of firewall for trigger. # Contains multiple subservices for each special # part of firewall. # # Author : Pierre-Elliott Bécue # Licence : GPLv3 # Date : 15/06/2014 """ Firewall service module. is uses the firewall library as it's, it is not designed to replace it, just to call specific functions from it to regenerate what needs to. """ import lc_ldap.shortcuts from gestion.trigger.host import record from gestion.trigger.services.service import BasicService import cranslib.clogger as clogger import gestion.config.firewall as firewall_config import gestion.trigger.firewall4.firewall4 as firewall4 logger = clogger.CLogger("trigger.firewall", "debug") class FwFunFactory(object): """Factory containing which function is part of the trigger set """ _meths = {} @classmethod def register(cls, key, value): """Stores in factory the function name and its value """ cls._meths[key] = value @classmethod def get(cls, key): """Gets what is stored """ return cls._meths.get(key, None) def fwrecord(function): """Records function in FwFunFactory """ FwFunFactory.register(function.func_name, function) def fwcall(fwfun): """Calls in function from FwFunFactory """ return FwFunFactory.get(fwfun) @record class firewall(BasicService): """Firewall service that handles any modification in the firewall. """ # Class lookup table to define which changes call which function. changes_trigger = { lc_ldap.attributs.macAddress.ldap_name: (firewall.send_mac_ip,), lc_ldap.attributs.ipHostNumber.ldap_name: (firewall.send_mac_ip,), } @classmethod def send_mac_ip(cls, body, diff): """Computes mac_ip data to send from body and diff """ macs = tuple([body[i].get(lc_ldap.attributs.macAddress.ldap_name, [''])[0] for i in xrange(1, 3)]) ips = tuple([body[i].get(lc_ldap.attributs.ipHostNumber.ldap_name, [''])[0] for i in xrange(1, 3)]) # Mise à jour du parefeu mac_ip if not macs[0]: # Création d'une nouvelle machine. fw = {'add': [(macs[1], ips[1])]} elif not macs[1]: # Destruction d'une machine. fw = {'delete': [(macs[0], ips[0])]} else: # Mise à jour. fw = {'update': [(macs[0], ips[0], macs[1], ips[1])]} return ("firewall", ("mac_ip", fw)) @classmethod def regen(cls, body=()): """Regens the specific service """ if len(body) != 2: logger.warning("Received body %r, this format is incorrect, discarding.", body) return (service, data) = body logger.info("Calling service %s for data %r", service, data) fwcall(service)(data) @fwrecord def mac_ip(body): host_fw = firewall4.firewall() if body and isinstance(body, dict): for (mac, ip) in body.get("add", []): logger.info("Adding mac_ip %s,%s", mac, ip) host_fw.mac_ip_append(mac, ip) for (mac, ip) in body.get("delete", []): logger.info("Removing mac_ip %s,%s", mac, ip) host_fw.mac_ip_remove(mac, ip) for (rmac, rip, mac, ip) in body.get("update", []): logger.info("Updating mac_ip %s,%s with %s,%s", rmac, rip, mac, ip) host_fw.mac_ip_remove(rmac, rip) host_fw.mac_ip_append(mac, ip)