123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- #!/usr/bin/python
- import datetime, collectd, os.path, ipaddress
- def parse_leases(lease_file):
- validKeys = ['lease', 'starts', 'ends', '}']
- leases = {}
- lease = {}
- for line in lease_file:
- tokens = line.split()
- if len(tokens) == 0 or tokens[0].startswith('#'):
- continue
- key = tokens[0].lower()
- if key in validKeys:
- if key == 'lease':
- lease = {'id' : tokens[1]}
- elif key == '}':
- if lease['id'] in leases:
- if leases[lease['id']]['ends'] < lease['ends']:
- leases[lease['id']] = lease
- else:
- leases[lease['id']] = lease
- else:
- lease[key] = tokens[2]+' '+tokens[3].rstrip(';')
- return leases
- def parse_dhcpd_conf(config_file):
- subnet = {}
- subnets = {}
- for line in config_file:
- line = line.strip().rstrip(';')
- tokens = line.split()
- if len(tokens) == 0 or tokens[0].startswith('#'):
- continue
- key = tokens[0].lower()
- if key == 'subnet':
- net = ipaddress.ip_network(unicode(tokens[1]+'/'+tokens[3]))
- subnet = {'netaddr_str' : tokens[1], 'netaddr_int' : int(net.network_address), 'netmask_str' : tokens[3], 'netmask_int' : int(net.netmask)}
-
- elif key == 'interface':
- subnet['interface'] = tokens[1]
- elif key == '}':
- subnet_add(subnets, subnet)
- subnet = {}
- return subnets
- def subnet_add(subnets, subnet):
- if 'interface' not in subnet:
- subnet['interface'] = 'global'
- sub_name = subnet['interface']
- if sub_name not in subnets:
- subnets[sub_name] = subnet
- else:
- pass #needs to be implemented
- def count_active_leases(all_leases, now, subnets):
- count_active = 0
- count_all = 0
- subnet_counter = {}
- for interface in subnets.iterkeys():
- subnet_counter[interface] = {'count_active': 0, 'count_all': 0, 'count_touch': 0}
- for lease in all_leases.itervalues():
- addr = int(ipaddress.ip_address(unicode(lease['id'])))
- for subnet in subnets.itervalues():
- if (addr & subnet['netmask_int']) == subnet['netaddr_int']:
- subnc = subnet_counter[subnet['interface']]
- subnc['count_all'] += 1
- count_all += 1
- if timestamp_inbetween(now, lease['starts'], lease['ends']):
- subnc['count_active'] += 1
- count_active += 1
- break
- for subnet in subnet_counter.itervalues():
- subnet['count_touch'] = subnet['count_all'] - subnet['count_active']
- count_touch = count_all - count_active
- return count_active, count_touch, subnet_counter
- def timestamp_inbetween(now, start, end):
- return start < now < end
- def read(data=None):
- configfile = '/etc/dhcp/dhcpd.conf'
- if os.path.isfile(configfile):
- cfile = open(configfile, 'r')
- config = parse_dhcpd_conf(cfile)
- leasefile = '/var/lib/dhcp/dhcpd.leases'
- if os.path.isfile(leasefile):
- lfile = open(leasefile, 'r')
- all_leases = parse_leases(lfile)
- lfile.close()
- count_active, count_touch, subnet_counter = count_active_leases(all_leases, datetime.datetime.utcnow().strftime("%Y/%m/%d %H:%M:%S"), config)
- vl = collectd.Values(type='dhcp_leases')
- vl.plugin='dhcp'
- vl.type_instance = 'all_interfaces'
- vl.dispatch(values=[count_active, count_touch])
- for k, v in subnet_counter.iteritems():
- vl = collectd.Values(type='dhcp_leases')
- vl.plugin='dhcp'
- vl.type_instance = k
- vl.dispatch(values=[v['count_active'], v['count_touch']])
- vl = collectd.Values(type='dhcp_leases')
- def write(vl, data=None):
- for i in vl.values:
- print "%s (%s): %f" % (vl.plugin, vl.type, i)
- collectd.register_read(read)
- collectd.register_write(write);
|