Mercurial > code > home > repos > homeauto
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 |
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 | 3 |
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 | 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 | 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 | 29 return Literal(dt.replace(tzinfo=tzlocal()).isoformat(), |
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 | 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 | 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 | 90 (r'/graph', CycloneGraphHandler, {'masterGraph': masterGraph}), |
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 | 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() |