|
@@ -4,6 +4,7 @@
|
|
|
from __future__ import print_function
|
|
|
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
|
|
|
|
|
|
+import cgi
|
|
|
from storage import Storage
|
|
|
import json
|
|
|
import logging
|
|
@@ -70,6 +71,23 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
|
|
|
# no match -> 404
|
|
|
self.send_error(404, 'The URL \'{0}\' was not found here.'.format(path))
|
|
|
|
|
|
+ def do_POST(self):
|
|
|
+ """Handles all HTTP POST requests."""
|
|
|
+
|
|
|
+ path, query = self.parse_url_pathquery()
|
|
|
+ if path is None:
|
|
|
+ self.send_error(400, 'Could not parse URL (' + str(self.path) + ')')
|
|
|
+ return
|
|
|
+ params = self.parse_post_params()
|
|
|
+
|
|
|
+ # node id/mac to name mapping
|
|
|
+ if path == 'idmac2name':
|
|
|
+ self.respond_nodeidmac2name(params)
|
|
|
+ return
|
|
|
+
|
|
|
+ # no match -> 404
|
|
|
+ self.send_error(404, 'The URL \'{0}\' was not found here.'.format(path))
|
|
|
+
|
|
|
def send_nocache_headers(self):
|
|
|
"""Sets HTTP headers indicating that this response shall not be cached."""
|
|
|
|
|
@@ -86,6 +104,17 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
|
|
|
if nocache: self.send_nocache_headers()
|
|
|
self.end_headers()
|
|
|
|
|
|
+ def parse_post_params(self):
|
|
|
+ ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
|
|
|
+ if ctype == 'multipart/form-data':
|
|
|
+ postvars = cgi.parse_multipart(self.rfile, pdict)
|
|
|
+ elif ctype == 'application/x-www-form-urlencoded':
|
|
|
+ length = int(self.headers.getheader('content-length'))
|
|
|
+ postvars = cgi.parse_qs(self.rfile.read(length), keep_blank_values=1)
|
|
|
+ else:
|
|
|
+ postvars = {}
|
|
|
+ return postvars
|
|
|
+
|
|
|
def respond_index(self, query):
|
|
|
"""Display the index page."""
|
|
|
|
|
@@ -162,6 +191,30 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
|
|
|
# return found node
|
|
|
return storage.data[nodeid] if nodeid in storage.data else None
|
|
|
|
|
|
+ def find_node_by_mac(self, mac):
|
|
|
+ """Fetch node data from storage by given MAC address."""
|
|
|
+
|
|
|
+ storage = self.server.storage
|
|
|
+ needle = mac.lower()
|
|
|
+
|
|
|
+ # iterate over all nodes
|
|
|
+ for nodeid in storage.data:
|
|
|
+ if nodeid.startswith('__'): continue
|
|
|
+ node = storage.data[nodeid]
|
|
|
+
|
|
|
+ # check node's primary MAC
|
|
|
+ if 'mac' in node and needle == node['mac'].lower():
|
|
|
+ return node
|
|
|
+
|
|
|
+ # check alias MACs
|
|
|
+ if 'macs' in node:
|
|
|
+ haystack = [ x.lower() for x in node['macs'] ]
|
|
|
+ if mac in haystack:
|
|
|
+ return node
|
|
|
+
|
|
|
+ # MAC address not found
|
|
|
+ return None
|
|
|
+
|
|
|
def respond_node(self, rawid):
|
|
|
"""Display node data."""
|
|
|
|
|
@@ -187,6 +240,15 @@ class BatcaveHttpRequestHandler(BaseHTTPRequestHandler):
|
|
|
self.send_headers('text/json')
|
|
|
self.wfile.write(json.dumps(node))
|
|
|
|
|
|
+ def respond_nodeidmac2name(self, ids):
|
|
|
+ storage = self.server.storage
|
|
|
+
|
|
|
+ self.send_headers('text/plain')
|
|
|
+ for nodeid in ids:
|
|
|
+ node = self.find_node(nodeid) if not ':' in nodeid else self.find_node_by_mac(nodeid)
|
|
|
+ nodename = node['hostname'] if (not node is None) and 'hostname' in node else nodeid
|
|
|
+ self.wfile.write('{0}={1}\n'.format(nodeid, nodename))
|
|
|
+
|
|
|
def respond_nodedetail(self, nodeid, field):
|
|
|
"""Return a field from the given node - a string is returned as text, all other as JSON."""
|
|
|
|