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