diff --git a/munin/stats-ip b/munin/stats-ip index 43ac330c..53b34b8c 100755 --- a/munin/stats-ip +++ b/munin/stats-ip @@ -1,51 +1,79 @@ -#!/usr/bin/env python +#!/bin/bash /usr/scripts/python.sh # -*- coding: utf-8 -*- +import ldap +import sys +from lc_ldap.shortcuts import lc_ldap_admin +from gestion.config import rid_primaires, NETs +from gestion.ridtools import Rid + # Plugin pour visualiser l'utilisation des plages ip -import sys -sys.path.append('/usr/scripts/gestion') -from config import NETs +TMP_FILE = "/var/lib/munin/tmp/stats-ip" -fichier = "/var/lib/munin/tmp/stats-ip" +def count_segment(dbc, first, last): + """Compte nb de rid entre first et last (inclu) dans la base ldap""" + return len( + dbc.search_ext_s('ou=data,dc=crans,dc=org', + scope=ldap.SCOPE_SUBTREE, + filterstr='(&(rid>=%d)(rid<=%d))' % (first, last), + attrsonly=0, attrlist=['rid'], + )) -try : +def count_rid(dbc, plages): + """Compte le nombre de rid d'une liste de plages, dans la base ldap""" + return sum(count_segment(dbc, first, last) for (first, last) in plages) + +def total_rid(plages): + """Total théorique du nombre de rid, dans une liste de plages, sans les + éventuels .0 et .255 (si ipv4 dispo)""" + tot = 0 + for (first, last) in plages: + tot += last - first + 1 + + # En vrai, il faut retirer les rids d'IPs en .255 ou .0, + # si ipv4 publique (bit 15 pas à 1) ou privée dispos (bit 14 pas à 0). + if first >> 14 != 0b10: + for xxx in [0, 255]: + # On calcule l'indice de la première et dernière IP en .xxx + # dans l'intervalle [first, last], à coup de division entière + jlast = (last-xxx)/256 # arrondi inf + jfirst = -((-first+xxx)/256) #arrondi sup + # Et donc on retire le nombre d'ip finissant en .xxx dans + # l'intervale + tot -= jlast - jfirst + 1 + + return tot + +try: arg = sys.argv[1] -except : +except: arg = '' +rids = {name: rid_primaires[name] for name in rid_primaires if name in NETs and + name != 'multicast'} + if arg == "config" : print 'host_name adresses-ip' print 'graph_title Statistiques adresses IP' print 'graph_args --base 1000 --lower-limit 0 --upper-limit 100' print 'graph_category network' print "graph_vlabel % d'utilisation" - for subnet in NETs.keys(): + for subnet in rids: nom = subnet.replace('-', '') print "%s.label %s" % (nom, subnet) print "%s.warning 92" % nom print "%s.critical 98" % nom elif arg == "fichier" : + db_conn = lc_ldap_admin() + out = file(TMP_FILE, "w") - from ldap_crans import crans_ldap - from iptools import AddrInNet - - ips = [ x.ip() for x in crans_ldap().search('ip=*')['machine'] ] - - out = file(fichier, "w") - - for subnet in NETs : - total = 0 - for net in NETs[subnet]: - total += 2 ** ( 32 - int( net.split('/')[1] ) ) - # on ne prend pas en compte les adresse .0 et .255 - total = total - int(total/128) - - utilisees = len( [ ip for ip in ips if AddrInNet( ip, NETs[subnet] ) ] ) - pourcentage = int((utilisees*100)/total) + for subnet in rids: + plages = rids[subnet] + pourcentage = int((count_rid(db_conn, plages)*100)/total_rid(plages)) nom = subnet.replace('-', '') out.write("%s.value %d\n" % (nom, pourcentage)) else: - print file(fichier).read() + print file(TMP_FILE).read()