mirror of https://github.com/ntop/n2n.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.2 KiB
118 lines
3.2 KiB
#!/usr/bin/env python3
|
|
# Licensed under GPLv3
|
|
#
|
|
# Simple http server to allow user control of n2n edge nodes
|
|
#
|
|
# Currently only for demonstration - needs javascript written to render the
|
|
# results properly.
|
|
#
|
|
# Try it out with
|
|
# http://localhost:8080/edge/peer
|
|
# http://localhost:8080/edge/super
|
|
|
|
import argparse
|
|
import socket
|
|
import json
|
|
import socketserver
|
|
import http.server
|
|
|
|
from http import HTTPStatus
|
|
|
|
next_tag = 0
|
|
|
|
|
|
def send_cmd(port, debug, cmd):
|
|
"""Send a text command to the edge and process the JSON reply packets"""
|
|
global next_tag
|
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
|
|
tagstr = str(next_tag)
|
|
next_tag = (next_tag + 1) % 1000
|
|
|
|
message = "{} {}".format(cmd, tagstr).encode('utf8')
|
|
sock.sendto(message, ("127.0.0.1", 5644))
|
|
|
|
# FIXME:
|
|
# - there is no timeout for any of the socket handling
|
|
|
|
begin, _ = sock.recvfrom(1024)
|
|
begin = json.loads(begin.decode('utf8'))
|
|
assert(begin['_tag'] == tagstr)
|
|
assert(begin['_type'] == 'begin')
|
|
assert(begin['_cmd'] == cmd)
|
|
|
|
result = list()
|
|
|
|
while True:
|
|
data, _ = sock.recvfrom(1024)
|
|
data = json.loads(data.decode('utf8'))
|
|
assert(data['_tag'] == tagstr)
|
|
|
|
if data['_type'] == 'unknowncmd':
|
|
raise ValueError('Unknown command {}'.format(cmd))
|
|
|
|
if data['_type'] == 'end':
|
|
return result
|
|
|
|
if data['_type'] != 'row':
|
|
raise ValueError('Unknown data type {} from '
|
|
'edge'.format(data['_type']))
|
|
|
|
# remove our boring metadata
|
|
del data['_tag']
|
|
del data['_type']
|
|
|
|
if debug:
|
|
print(data)
|
|
|
|
result.append(data)
|
|
|
|
|
|
class SimpleHandler(http.server.BaseHTTPRequestHandler):
|
|
|
|
def log_request(self, code='-', size='-'):
|
|
# Dont spam the output
|
|
pass
|
|
|
|
def do_GET(self):
|
|
url_tail = self.path
|
|
if url_tail.startswith("/edge/"):
|
|
tail = url_tail.split('/')
|
|
cmd = 'j.' + tail[2]
|
|
|
|
try:
|
|
data = send_cmd(5644, False, cmd)
|
|
except ValueError:
|
|
self.send_response(HTTPStatus.BAD_REQUEST)
|
|
self.end_headers()
|
|
self.wfile.write(b'Bad Command')
|
|
return
|
|
|
|
self.send_response(HTTPStatus.OK)
|
|
self.send_header('Content-type', 'application/json')
|
|
self.end_headers()
|
|
self.wfile.write(json.dumps(data).encode('utf8'))
|
|
|
|
|
|
def main():
|
|
ap = argparse.ArgumentParser(
|
|
description='Control the running local n2n edge via http')
|
|
# TODO - this needs to pass into the handler object
|
|
# ap.add_argument('-t', '--mgmtport', action='store', default=5644,
|
|
# help='Management Port (default=5644)')
|
|
# ap.add_argument('-d', '--debug', action='store_true',
|
|
# help='Also show raw internal data')
|
|
ap.add_argument('port', action='store',
|
|
default=8080, type=int, nargs='?',
|
|
help='Serve requests on TCP port (default 8080)')
|
|
|
|
args = ap.parse_args()
|
|
|
|
with socketserver.TCPServer(("", args.port), SimpleHandler) as httpd:
|
|
httpd.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
httpd.serve_forever()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|