# -*- coding: utf-8 -*- """ Génération de la configuration pour le dhcp Copyright (C) Frédéric Pauget Licence : GPLv2 """ import os import sys from socket import gethostname import struct if '/usr/scripts' not in sys.path: sys.path.append('/usr/scripts') from gestion.iptools import AddrInNet from gestion.gen_confs import gen_config from gestion.config import NETs from gestion.config.services import services from gestion import secrets_new as secrets # Relative imports from pypureomapi import pack_ip, pack_mac, OMAPI_OP_UPDATE from pypureomapi import Omapi, OmapiMessage, OmapiError, OmapiErrorNotFound hostname = gethostname().split(".")[0] class dydhcp: def __init__(self, server): self.dhcp_omapi_keyname = secrets.get('dhcp_omapi_keyname') self.dhcp_omapi_key = secrets.get('dhcp_omapi_keys')[server] self.server = server.lower() def add_host(self, ip, mac,name=None): """ @type ip: str @type mac: str @type name: str @raises ValueError: @raises OmapiError: @raises socket.error: """ 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(self.server, 9991,self.dhcp_omapi_keyname, self.dhcp_omapi_key) response = conn.query_server(msg) conn.close() def del_host(self, ip,mac): """ @type ip: str @type mac: str @raises ValueError: @raises OmapiError: @raises socket.error: """ 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(self.server,9991,self.dhcp_omapi_keyname, self.dhcp_omapi_key) response = conn.query_server(msg) if response.opcode == OMAPI_OP_UPDATE: response = conn.query_server(OmapiMessage.delete(response.handle)) conn.close() class dhcp(gen_config) : """ Génération du fichier de déclaration des hosts. Chaque réseau servi doit être une clef du dictionnaire reseaux, la valeur correspondante est une chaine contenant le nom du fichier associé à ce réseau. Chaque machine possède ensuite une entrée de la forme de host_template. """ ######################################PARTIE DE CONFIGURATION # Fichier à écire if hostname in services.get('isc-dhcp-server', []): restart_cmd = '/usr/bin/monit restart isc-dhcp-server' reseaux = { '138.231.136.0/21' : '/etc/dhcp3/generated/adherents.liste', '10.42.0.0/16' : '/etc/dhcp3/generated/gratuit.liste', '10.2.9.0/24' : '/etc/dhcp3/generated/appartements.liste', '138.231.144.0/21' : '/etc/dhcp3/generated/wifi.liste' } else: restart_cmd = '' reseaux = {} dhcplease='/var/lib/dhcp/dhcpd.leases' host_template = """ host %(nom)s { hardware ethernet %(mac)s; fixed-address %(ip)s; option host-name "%(host)s"; } """ ### Verbosité # Si =1 ralera (chaine warnings) si machines hors zone trouvée # Si =0 ralera seulement si réseau vide verbose = 1 ######################################FIN PARTIE DE CONFIGURATION def __str__(self) : return 'dhcp' def lease_clean(self): f=open(self.dhcplease) w=open(self.dhcplease+'.new','w') config="" line=f.readline() write=True while line: if line.strip().startswith('host'): write=False if write: w.write(line) if not write and line.strip().endswith('}'): write=True line=f.readline() f.close() w.close() os.rename(self.dhcplease+'.new',self.dhcplease) return def _gen(self) : """Construction de la liste des machines appartenant à un réseau """ warnings = '' ### Construction de la partie du fichier contenant les machines hosts = {} self.anim.iter = len(self.machines) for machine in self.machines : self.anim.cycle() for net in self.reseaux.keys() : if '' not in [machine.ip(), machine.mac()] and \ AddrInNet(machine.ip(), net): host_template = self.host_template # variable pour remplir le template #d = { 'nom' : machine.nom().split('.')[0] , 'mac' : machine.mac() , 'ip' : machine.ip() } d = { 'nom' : machine.nom() , 'host' : machine.nom().split('.', 1)[0],'mac' : machine.mac() , 'ip' : machine.ip() } try : hosts[net] += host_template % d except : hosts[net] = host_template % d ### Ecriture du fichier for net, fichier in self.reseaux.items() : fd0 = self._open_conf(fichier, '#') if hosts.has_key(net): fd0.write(hosts[net]) fd0.close() try: self.lease_clean() except: print("An error append during cleaning of dhcp lease") return warnings