#! /usr/bin/env python # -*- coding: utf-8 -*- """ Génération de la configuration pour le dhcp Copyright (C) Frédéric Pauget Licence : GPLv2 """ import os from iptools import AddrInNet from gen_confs import gen_config from ldap_crans import hostname from config import NETs from pypureomapi import pack_ip, pack_mac, OMAPI_OP_UPDATE from pypureomapi import Omapi, OmapiMessage, OmapiError, OmapiErrorNotFound import struct class dydhcp: def __init__(self): import sys sys.path.append('/usr/scripts/gestion/secrets') from secrets import dhcp_omapi_keyname,dhcp_omapi_key self.dhcp_omapi_keyname=dhcp_omapi_keyname self.dhcp_omapi_key=dhcp_omapi_key def add_host(self, ip, mac,name=None): """ @type ip: str @type mac: str @type name: str @raises ValueError: @raises OmapiError: @raises socket.error: """ 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('dhcp.adm.crans.org',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: """ 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('dhcp.adm.crans.org',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 == 'sable': restart_cmd = '/etc/init.d/isc-dhcp-server restart' reseaux = { '138.231.136.0/21' : '/etc/dhcp3/generated/adherents.liste', '10.42.0.0/16' : '/etc/dhcp3/generated/gratuit.liste' } elif hostname == 'titanic': restart_cmd = '/etc/init.d/isc-dhcp-server restart' reseaux = { '10.2.9.0/24' : '/etc/dhcp3/generated/appartements.liste' } elif hostname == 'gordon': restart_cmd = '/etc/init.d/isc-dhcp-server restart' reseaux = { '138.231.144.0/21' : '/etc/dhcp3/generated/wifi.liste' } elif hostname == 'dhcp': restart_cmd = '/etc/init.d/isc-dhcp-server restart' 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' } elif hostname == 'isc': restart_cmd = '/etc/init.d/isc-dhcp-server restart' 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"; } """ host_template_ltsp_powerpc = """ host %(nom)s { hardware ethernet %(mac)s; fixed-address %(ip)s; option host-name "%(host)s"; next-server 138.231.136.98; filename "yaboot"; option root-path "/opt/ltsp/powerpc"; } """ ### 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 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('.')[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