[trigger] Going back to simplified version
This commit is contained in:
parent
8068f057e0
commit
091a2d161e
6 changed files with 287 additions and 292 deletions
|
@ -18,212 +18,186 @@ import struct
|
|||
|
||||
import gestion.config.trigger as trigger_config
|
||||
import cranslib.clogger as clogger
|
||||
logger = clogger.CLogger("trigger", "dhcp", "debug", trigger_config.debug)
|
||||
logger = clogger.CLogger("trigger", "dhcp", trigger_config.log_level, trigger_config.debug)
|
||||
|
||||
hostname = socket.gethostname().split(".")[0] + ".adm.crans.org"
|
||||
hostname = socket.gethostname().split(".")[0]
|
||||
hostname_adm = hostname + ".adm.crans.org"
|
||||
|
||||
import lc_ldap.shortcuts
|
||||
from gestion.trigger.services.service import BasicService
|
||||
from cranslib.conffile import ConfFile
|
||||
import gestion.config.dhcp as dhcp_config
|
||||
import gestion.secrets_new as secrets_new
|
||||
import gestion.affichage as affichage
|
||||
import gestion.iptools as iptools
|
||||
from gestion.trigger.pypureomapi import pack_ip, pack_mac, OMAPI_OP_UPDATE
|
||||
from gestion.trigger.pypureomapi import Omapi, OmapiMessage
|
||||
|
||||
|
||||
class Dhcp(BasicService):
|
||||
"""Class responsible of dhcp service.
|
||||
|
||||
"""
|
||||
|
||||
# Class lookup table to define which changes call which function.
|
||||
changes_trigger = {
|
||||
lc_ldap.attributs.macAddress.ldap_name: ('send_mac_ip',),
|
||||
lc_ldap.attributs.ipHostNumber.ldap_name: ('send_mac_ip',),
|
||||
}
|
||||
from gestion.trigger.pypureomapi import pack_ip, pack_mac, OMAPI_OP_UPDATE, Omapi, OmapiMessage
|
||||
from gestion.trigger.host import record_service, record_parser, TriggerFactory
|
||||
|
||||
if "dhcp" in trigger_config.services[hostname]:
|
||||
dhcp_omapi_keyname = secrets_new.get("dhcp_omapi_keyname")
|
||||
dhcp_omapi_key = secrets_new.get("dhcp_omapi_keys")[hostname_adm]
|
||||
ldap_conn = lc_ldap.shortcuts.lc_ldap_readonly()
|
||||
else:
|
||||
dhcp_omapi_keyname = None
|
||||
dhcp_omapi_key = None
|
||||
ldap_conn = None
|
||||
|
||||
@classmethod
|
||||
def send_mac_ip(cls, body, diff):
|
||||
"""Computes mac_ip data to send from body and diff
|
||||
@record_parser(lc_ldap.attributs.macAddress.ldap_name, lc_ldap.attributs.ipHostNumber.ldap_name)
|
||||
def send_mac_ip(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)])
|
||||
hostnames = tuple([body[i].get(lc_ldap.attributs.host.ldap_name, [''])[0] for i in xrange(1, 3)])
|
||||
"""
|
||||
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)])
|
||||
hostnames = tuple([body[i].get(lc_ldap.attributs.host.ldap_name, [''])[0] for i in xrange(1, 3)])
|
||||
|
||||
# Régénération du DHCP :
|
||||
if not macs[0]:
|
||||
# Création d'une nouvelle machine.
|
||||
dhcp_dict = {'add': [(macs[1], ips[1], hostnames[1])]}
|
||||
elif not macs[1]:
|
||||
# Destruction d'une machine.
|
||||
dhcp_dict = {'delete': [(macs[0], ips[0])]}
|
||||
else:
|
||||
# Mise à jour.
|
||||
dhcp_dict = {'update': [(macs[0], ips[0], macs[1], ips[1], hostnames[1])]}
|
||||
return ("dhcp", dhcp_dict)
|
||||
# Régénération du DHCP :
|
||||
if not macs[0]:
|
||||
# Création d'une nouvelle machine.
|
||||
dhcp_dict = {'add': [(macs[1], ips[1], hostnames[1])]}
|
||||
elif not macs[1]:
|
||||
# Destruction d'une machine.
|
||||
dhcp_dict = {'delete': [(macs[0], ips[0])]}
|
||||
else:
|
||||
# Mise à jour.
|
||||
dhcp_dict = {'update': [(macs[0], ips[0], macs[1], ips[1], hostnames[1])]}
|
||||
return ("dhcp", dhcp_dict)
|
||||
|
||||
@classmethod
|
||||
def regen(cls, body=None):
|
||||
"""Regenerates dhcp service taking body into account.
|
||||
@record_service
|
||||
def dhcp(body=None):
|
||||
"""Regenerates dhcp service taking body into account.
|
||||
|
||||
"""
|
||||
cls.check_params()
|
||||
"""
|
||||
|
||||
# http://satyajit.ranjeev.in/2012/01/12/python--dangerous-default-value-as-argument.html
|
||||
# dict are referenced.
|
||||
if body is None:
|
||||
body = {}
|
||||
# http://satyajit.ranjeev.in/2012/01/12/python--dangerous-default-value-as-argument.html
|
||||
# dict are referenced.
|
||||
if body is None:
|
||||
body = {}
|
||||
|
||||
if body and isinstance(body, dict):
|
||||
for (mac, ip, name) in body.get("add", []):
|
||||
logger.info("Updating DHCP db by adding %s, %s, %s", mac, ip, name)
|
||||
# XXX - Uncommend this when we need to start prod
|
||||
# cls.add_dhcp_host(mac, ip, name)
|
||||
for (mac, ip) in body.get("delete", []):
|
||||
logger.info("Updating DHCP db by deleting %s, %s", mac, ip)
|
||||
# XXX - Uncommend this when we need to start prod
|
||||
# cls.delete_dhcp_host(mac, ip)
|
||||
for (rmac, rip, mac, ip, name) in body.get("update", []):
|
||||
logger.info("Updating DHCP db by modifying %s, %s to %s, %s, %s", rmac, rip, mac, ip, name)
|
||||
# XXX - Uncommend this when we need to start prod
|
||||
# cls.delete_dhcp_host(rmac, rip)
|
||||
# cls.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";
|
||||
}
|
||||
if body and isinstance(body, dict):
|
||||
for (mac, ip, name) in body.get("add", []):
|
||||
logger.info("Updating DHCP db by adding %s, %s, %s", mac, ip, name)
|
||||
# XXX - Uncommend this when we need to start prod
|
||||
# add_dhcp_host(mac, ip, name)
|
||||
for (mac, ip) in body.get("delete", []):
|
||||
logger.info("Updating DHCP db by deleting %s, %s", mac, ip)
|
||||
# XXX - Uncommend this when we need to start prod
|
||||
# delete_dhcp_host(mac, ip)
|
||||
for (rmac, rip, mac, ip, name) in body.get("update", []):
|
||||
logger.info("Updating DHCP db by modifying %s, %s to %s, %s, %s", rmac, rip, mac, ip, name)
|
||||
# XXX - Uncommend this when we need to start prod
|
||||
# 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 = cls.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)
|
||||
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 '<automatique>' 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()
|
||||
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 '<automatique>' 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])
|
||||
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
|
||||
|
||||
step = "Nettoyage des fichiers de leases"
|
||||
affichage.prettyDoin(step, "...")
|
||||
try:
|
||||
cls.lease_clean()
|
||||
affichage.prettyDoin(step, "Ok")
|
||||
except:
|
||||
affichage.prettyDoin(step, "Erreur")
|
||||
print "During lease clean, an error occured."
|
||||
raise
|
||||
|
||||
@classmethod
|
||||
def check_params(cls):
|
||||
"""This method allows lazy evaluation for dhcp_omapi_keyname
|
||||
and dhcp_omapi_key, since event imports all services. This is actually
|
||||
the best lazy eval we can hope, since property won't work on
|
||||
classmethods.
|
||||
def add_dhcp_host(mac, ip, name=None):
|
||||
"""Adds a dhcp host using omapi
|
||||
|
||||
"""
|
||||
if cls.dhcp_omapi_keyname is None:
|
||||
cls.dhcp_omapi_keyname = secrets_new.get("dhcp_omapi_keyname")
|
||||
if cls.dhcp_omapi_key is None:
|
||||
cls.dhcp_omapi_key = secrets_new.get("dhcp_omapi_keys")[hostname]
|
||||
if cls.ldap_conn is None:
|
||||
cls.ldap_conn = lc_ldap.shortcuts.lc_ldap_readonly()
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def add_dhcp_host(cls, mac, ip, name=None):
|
||||
"""Adds a dhcp host using omapi
|
||||
if '<automatique>' 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_adm, 9991, dhcp_omapi_keyname, dhcp_omapi_key)
|
||||
_ = conn.query_server(msg)
|
||||
conn.close()
|
||||
|
||||
"""
|
||||
cls.check_params()
|
||||
|
||||
if '<automatique>' 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, cls.dhcp_omapi_keyname, cls.dhcp_omapi_key)
|
||||
_ = conn.query_server(msg)
|
||||
conn.close()
|
||||
def delete_dhcp_host(mac, ip):
|
||||
"""Deletes dhcp host using omapi
|
||||
|
||||
@classmethod
|
||||
def delete_dhcp_host(cls, mac, ip):
|
||||
"""Deletes dhcp host using omapi
|
||||
"""
|
||||
|
||||
"""
|
||||
cls.check_params()
|
||||
if '<automatique>' 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_adm, 9991, dhcp_omapi_keyname, dhcp_omapi_key)
|
||||
response = conn.query_server(msg)
|
||||
if response.opcode == OMAPI_OP_UPDATE:
|
||||
_ = conn.query_server(OmapiMessage.delete(response.handle))
|
||||
conn.close()
|
||||
|
||||
if '<automatique>' 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, cls.dhcp_omapi_keyname, cls.dhcp_omapi_key)
|
||||
response = conn.query_server(msg)
|
||||
if response.opcode == OMAPI_OP_UPDATE:
|
||||
_ = conn.query_server(OmapiMessage.delete(response.handle))
|
||||
conn.close()
|
||||
|
||||
@staticmethod
|
||||
def lease_clean():
|
||||
"""Clean the lease file
|
||||
def lease_clean():
|
||||
"""Clean the lease file
|
||||
|
||||
"""
|
||||
# TODO : use ConfigFile structure
|
||||
leasefile = open(dhcp_config.dhcplease)
|
||||
newleasefile = open(dhcp_config.dhcplease + '.new', 'w')
|
||||
"""
|
||||
# TODO : use ConfigFile structure
|
||||
leasefile = open(dhcp_config.dhcplease)
|
||||
newleasefile = open(dhcp_config.dhcplease + '.new', 'w')
|
||||
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()
|
||||
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)
|
||||
|
||||
leasefile.close()
|
||||
newleasefile.close()
|
||||
os.rename(dhcp_config.dhcplease+'.new', dhcp_config.dhcplease)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue