annotate service/dhcpleases/dhcpleases.py @ 1334:73c2b13692b7

rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff Ignore-this: 2dffc17b676253d4fec234fc096db4d5 darcs-hash:be3903ed924e998edd207ac4d8ae336bc64243ba
author drewp <drewp@bigasterisk.com>
date Tue, 23 Apr 2019 02:56:07 -0700
parents d36cd59b145a
children a93fbf0d0daa
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
966
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
1 """
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
2 statements about dhcp leases (and maybe live-host pings)
1283
d36cd59b145a dhcpleases partial rewrite
drewp <drewp@bigasterisk.com>
parents: 1008
diff changeset
3
d36cd59b145a dhcpleases partial rewrite
drewp <drewp@bigasterisk.com>
parents: 1008
diff changeset
4 also read 'arp -an' and our dns list
966
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
5 """
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
6 import datetime, itertools, os
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
7
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
8 from docopt import docopt
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
9 from dateutil.tz import tzlocal
1283
d36cd59b145a dhcpleases partial rewrite
drewp <drewp@bigasterisk.com>
parents: 1008
diff changeset
10 from rdflib import URIRef, Namespace, Literal, RDF, RDFS, XSD, ConjunctiveGraph
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
11 from twisted.internet import reactor, task
966
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
12 import cyclone.web
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
13
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
14 from greplin import scales
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
15 from greplin.scales.cyclonehandler import StatsHandler
1283
d36cd59b145a dhcpleases partial rewrite
drewp <drewp@bigasterisk.com>
parents: 1008
diff changeset
16 from patchablegraph import PatchableGraph, CycloneGraphEventsHandler, CycloneGraphHandler
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
17 from standardservice.logsetup import log, verboseLogging
966
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
18
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
19 DEV = Namespace("http://projects.bigasterisk.com/device/")
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
20 ROOM = Namespace("http://projects.bigasterisk.com/room/")
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
21 ctx = DEV['dhcp']
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
22
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
23 STATS = scales.collection('/root',
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
24 scales.PmfStat('readLeases'),
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
25 scales.IntStat('filesDidntChange'),
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
26 )
966
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
27
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
28 def timeLiteral(dt):
967
2489d111f4f1 whitespace
drewp <drewp@bigasterisk.com>
parents: 966
diff changeset
29 return Literal(dt.replace(tzinfo=tzlocal()).isoformat(),
2489d111f4f1 whitespace
drewp <drewp@bigasterisk.com>
parents: 966
diff changeset
30 datatype=XSD.dateTime)
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
31
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
32 def macUri(macAddress: str) -> URIRef:
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
33 return URIRef("http://bigasterisk.com/mac/%s" % macAddress.lower())
966
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
34
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
35 class Poller:
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
36 def __init__(self, graph):
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
37 self.graph = graph
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
38 self.fileTimes = {'/opt/dnsmasq/10.1/leases': 0, '/opt/dnsmasq/10.2/leases': 0}
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
39 task.LoopingCall(self.poll).start(2)
1283
d36cd59b145a dhcpleases partial rewrite
drewp <drewp@bigasterisk.com>
parents: 1008
diff changeset
40
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
41 def anythingToRead(self):
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
42 ret = False
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
43 for f, t in self.fileTimes.items():
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
44 mtime = os.path.getmtime(f)
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
45 if mtime > t:
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
46 self.fileTimes[f] = mtime
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
47 ret = True
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
48 return ret
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
49
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
50 def poll(self):
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
51 if not self.anythingToRead():
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
52 STATS.filesDidntChange += 1
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
53 return
966
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
54
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
55 with STATS.readLeases.time():
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
56 g = ConjunctiveGraph()
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
57 for line in itertools.chain(*[open(f) for f in self.fileTimes]):
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
58 # http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2016q2/010595.html
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
59 expiration_secs, addr, ip, hostname, clientid = line.strip().split(' ')
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
60
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
61 uri = macUri(addr)
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
62 g.add((uri, RDF.type, ROOM['HasDhcpLease'], ctx))
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
63 g.add((uri, ROOM['macAddress'], Literal(addr), ctx))
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
64 g.add((uri, ROOM['assignedIp'], Literal(ip), ctx))
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
65
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
66 if hostname != '*':
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
67 g.add((uri, ROOM['dhcpHostname'], Literal(hostname), ctx))
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
68
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
69 self.graph.setToGraph(g)
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
70
966
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
71 if __name__ == '__main__':
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
72 arg = docopt("""
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
73 Usage: store.py [options]
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
74
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
75 -v Verbose
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
76 --port PORT Serve on port [default: 9073].
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
77 """)
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
78
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
79 verboseLogging(arg['-v'])
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
80
1283
d36cd59b145a dhcpleases partial rewrite
drewp <drewp@bigasterisk.com>
parents: 1008
diff changeset
81 masterGraph = PatchableGraph()
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
82 poller = Poller(masterGraph)
966
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
83
979
76bb0bf74bd1 new index page. fix dhcp scanner errors
drewp <drewp@bigasterisk.com>
parents: 967
diff changeset
84 reactor.listenTCP(
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
85 int(arg['--port']),
979
76bb0bf74bd1 new index page. fix dhcp scanner errors
drewp <drewp@bigasterisk.com>
parents: 967
diff changeset
86 cyclone.web.Application(
76bb0bf74bd1 new index page. fix dhcp scanner errors
drewp <drewp@bigasterisk.com>
parents: 967
diff changeset
87 [
76bb0bf74bd1 new index page. fix dhcp scanner errors
drewp <drewp@bigasterisk.com>
parents: 967
diff changeset
88 (r"/()", cyclone.web.StaticFileHandler,
76bb0bf74bd1 new index page. fix dhcp scanner errors
drewp <drewp@bigasterisk.com>
parents: 967
diff changeset
89 {"path": ".", "default_filename": "index.html"}),
1283
d36cd59b145a dhcpleases partial rewrite
drewp <drewp@bigasterisk.com>
parents: 1008
diff changeset
90 (r'/graph', CycloneGraphHandler, {'masterGraph': masterGraph}),
d36cd59b145a dhcpleases partial rewrite
drewp <drewp@bigasterisk.com>
parents: 1008
diff changeset
91 (r'/graph/events', CycloneGraphEventsHandler, {'masterGraph': masterGraph}),
1334
73c2b13692b7 rewrite dhcpleases to use dnsmasq's data files, and all the new build stuff
drewp <drewp@bigasterisk.com>
parents: 1283
diff changeset
92 (r'/stats/(.*)', StatsHandler, {'serverName': 'dhcpleases'}),
1283
d36cd59b145a dhcpleases partial rewrite
drewp <drewp@bigasterisk.com>
parents: 1008
diff changeset
93 ], masterGraph=masterGraph
979
76bb0bf74bd1 new index page. fix dhcp scanner errors
drewp <drewp@bigasterisk.com>
parents: 967
diff changeset
94 ))
966
cce0107a78b4 scan dhcpd.leases to get more info about networked devices
drewp <drewp@bigasterisk.com>
parents:
diff changeset
95 reactor.run()