From 07678300da04dc98efa07d59e7524739fa2cc9df Mon Sep 17 00:00:00 2001 From: Donald Cheng Hong Zou Date: Fri, 2 Apr 2021 20:48:00 -0400 Subject: [PATCH] v20210402 Added more features --- .gitignore | 6 +- src/dashboard.py | 110 +++++++++++-- src/db/hi.txt | 1 + src/static/bootstrap4-toggle.min.js | 1 + src/static/configuration.png | Bin 466219 -> 112545 bytes src/static/dashboard.css | 18 +++ src/static/index.png | Bin 72262 -> 50685 bytes src/templates/configuration.html | 229 ++++++++++++++-------------- src/templates/get_conf.html | 112 ++++++++++++++ src/test.py | 4 - 10 files changed, 349 insertions(+), 132 deletions(-) create mode 100644 src/db/hi.txt create mode 100644 src/static/bootstrap4-toggle.min.js create mode 100644 src/templates/get_conf.html delete mode 100644 src/test.py diff --git a/.gitignore b/.gitignore index b79ff9c..c1dc8aa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ .vscode/sftp.json src/.vscode/sftp.json -.DS_Store \ No newline at end of file +.DS_Store +wg.db +*.json +.idea +src/test.py diff --git a/src/dashboard.py b/src/dashboard.py index 60033e2..190b75b 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -2,19 +2,21 @@ import os from flask import Flask, request, render_template, redirect, url_for import subprocess from datetime import datetime, date, time, timedelta -from tinydb import TinyDB, Query +import sqlite3 import time import requests - - +from operator import itemgetter +import collections +from tinydb import TinyDB, Query conf_location = "/etc/wireguard" - app = Flask("Wireguard Dashboard") app.config['TEMPLATES_AUTO_RELOAD'] = True css = "" conf_data = {} + + def get_conf_peer_key(config_name): keys = [] try: peer_key = subprocess.check_output("wg show "+config_name+" peers", shell=True) @@ -41,12 +43,31 @@ def get_conf_running_peer_number(config_name): return running def get_conf_peers_data(config_name): + db = TinyDB('db/'+config_name+'.json') + peers = Query() peer_data = {} # Get key try: peer_key = subprocess.check_output("wg show "+config_name+" peers", shell=True) except Exception: return "stopped" peer_key = peer_key.decode("UTF-8").split() - for i in peer_key: peer_data[i] = {} + for i in peer_key: + peer_data[i] = {} + if not db.search(peers.id == i): + db.insert({ + "id": i, + "name": "", + "total_receive": 0, + "total_sent": 0, + "total_data": 0, + "endpoint": 0, + "status": 0, + "latest_handshake": 0, + "allowed_ip": 0, + "traffic": [] + }) + + + #Get transfer try: data_usage = subprocess.check_output("wg show "+config_name+" transfer", shell=True) @@ -57,7 +78,11 @@ def get_conf_peers_data(config_name): download_total = 0 total = 0 for i in range(int(len(data_usage)/3)): - peer_data[data_usage[count]]['total_recive'] = round(int(data_usage[count+1])/(1024**3),4) + db.update({"total_receive": round(int(data_usage[count+1])/(1024**3),4), + "total_sent": round(int(data_usage[count+2])/(1024**3),4), + "total_data": round((int(data_usage[count+2])+int(data_usage[count+1]))/(1024**3),4)}, peers.id == data_usage[count]) + + peer_data[data_usage[count]]['total_receive'] = round(int(data_usage[count+1])/(1024**3),4) peer_data[data_usage[count]]['total_sent'] = round(int(data_usage[count+2])/(1024**3),4) peer_data[data_usage[count]]['total_data'] = round((int(data_usage[count+2])+int(data_usage[count+1]))/(1024**3),4) count += 3 @@ -68,6 +93,8 @@ def get_conf_peers_data(config_name): data_usage = data_usage.decode("UTF-8").split() count = 0 for i in range(int(len(data_usage)/2)): + db.update({"endpoint": data_usage[count+1]}, peers.id == data_usage[count]) + peer_data[data_usage[count]]['endpoint'] = data_usage[count+1] count += 2 @@ -80,11 +107,16 @@ def get_conf_peers_data(config_name): b = timedelta(minutes=2) for i in range(int(len(data_usage)/2)): minus = now - datetime.fromtimestamp(int(data_usage[count+1])) + status = "" if minus < b: peer_data[data_usage[count]]['status'] = "running" + status = "running" else: peer_data[data_usage[count]]['status'] = "stopped" - peer_data[data_usage[count]]['latest_handshake'] = minus + status = "stopped" + + db.update({"latest_handshake": str(minus).split(".")[0], "status": status}, peers.id == data_usage[count]) + peer_data[data_usage[count]]['latest_handshake'] = str(minus).split(".")[0] count += 2 #Get allowed ip @@ -93,27 +125,30 @@ def get_conf_peers_data(config_name): data_usage = data_usage.decode("UTF-8").split() count = 0 for i in range(int(len(data_usage)/2)): + db.update({"allowed_ip": data_usage[count+1]}, peers.id == data_usage[count]) peer_data[data_usage[count]]['allowed_ip'] = data_usage[count+1] count += 2 - - return peer_data + + result = db.all() + result = sorted(result, key=lambda d: d['status']) + return result def get_conf_pub_key(config_name): - try: pub_key = subprocess.check_output("wg show "+config_name+" public-key", shell=True) + try: pub_key = subprocess.check_output("wg show "+config_name+" public-key", shell=True, stderr=subprocess.STDOUT) except Exception: return "stopped" return pub_key.decode("UTF-8") def get_conf_listen_port(config_name): - try: pub_key = subprocess.check_output("wg show "+config_name+" listen-port", shell=True) + try: pub_key = subprocess.check_output("wg show "+config_name+" listen-port", shell=True, stderr=subprocess.STDOUT) except Exception: return "stopped" return pub_key.decode("UTF-8") def get_conf_total_data(config_name): - try: data_usage = subprocess.check_output("wg show "+config_name+" transfer", shell=True) + try: data_usage = subprocess.check_output("wg show "+config_name+" transfer", shell=True, stderr=subprocess.STDOUT) except Exception: return "stopped" data_usage = data_usage.decode("UTF-8").split() count = 0 @@ -133,7 +168,7 @@ def get_conf_total_data(config_name): def get_conf_status(config_name): - try: status = subprocess.check_output("wg show "+config_name, shell=True) + try: status = subprocess.check_output("wg show "+config_name, shell=True, stderr=subprocess.STDOUT) except Exception: return "stopped" else: return "running" @@ -148,6 +183,7 @@ def get_conf_list(): temp['checked'] = 'checked' else: temp['checked'] = "" conf.append(temp) + conf = sorted(conf, key=itemgetter('status')) return conf @app.route('/',methods=['GET']) @@ -157,6 +193,21 @@ def index(): @app.route('/configuration/', methods=['GET']) def conf(config_name): + conf_data = { + "name": config_name, + "status": get_conf_status(config_name), + "checked": "" + } + if conf_data['status'] == "stopped": + return redirect('/') + else: + conf_data['checked'] = "checked" + return render_template('configuration.html', conf=get_conf_list(), conf_data=conf_data) + +@app.route('/get_config/', methods=['GET']) +def get_conf(config_name): + db = TinyDB('db/'+config_name+'.json') + conf_data = { "name": config_name, "status": get_conf_status(config_name), @@ -165,14 +216,12 @@ def conf(config_name): "listen_port": get_conf_listen_port(config_name), "peer_data":get_conf_peers_data(config_name), "running_peer": get_conf_running_peer_number(config_name), - "checked": "" } if conf_data['status'] == "stopped": - print(conf_data) return redirect('/') else: conf_data['checked'] = "checked" - return render_template('configuration.html', conf=get_conf_list(), conf_data=conf_data) + return render_template('get_conf.html', conf=get_conf_list(), conf_data=conf_data) @app.route('/switch/', methods=['GET']) @@ -208,6 +257,8 @@ def add_peer(config_name): @app.route('/remove_peer/', methods=['POST']) def remove_peer(config_name): + db = TinyDB("db/"+config_name+".json") + peers = Query() data = request.get_json() delete_key = data['peer_id'] keys = get_conf_peer_key(config_name) @@ -217,8 +268,35 @@ def remove_peer(config_name): try: status = subprocess.check_output("wg set "+config_name+" peer "+delete_key+" remove", shell=True, stderr=subprocess.STDOUT) status = subprocess.check_output("wg-quick save "+config_name, shell=True, stderr=subprocess.STDOUT) + db.remove(peers.id == delete_key) return "true" except subprocess.CalledProcessError as exc: return exc.output.strip() +@app.route('/save_peer_name/', methods=['POST']) +def save_peer_name(config_name): + data = request.get_json() + id = data['id'] + name = data['name'] + db = TinyDB("db/"+config_name+".json") + peers = Query() + + db.update({"name": name}, peers.id == id) + return id + " " + name + +@app.route('/get_peer_name/', methods=['POST']) +def get_peer_name(config_name): + data = request.get_json() + id = data['id'] + db = TinyDB("db/"+config_name+".json") + peers = Query() + result = db.search(peers.id == id) + return result[0]['name'] + # db.update({"name": name}, peers.id == id) + + + + + + app.run(host='0.0.0.0',debug=False, port=10086) \ No newline at end of file diff --git a/src/db/hi.txt b/src/db/hi.txt new file mode 100644 index 0000000..035ff7e --- /dev/null +++ b/src/db/hi.txt @@ -0,0 +1 @@ +You can delete this later ;) \ No newline at end of file diff --git a/src/static/bootstrap4-toggle.min.js b/src/static/bootstrap4-toggle.min.js new file mode 100644 index 0000000..62f757f --- /dev/null +++ b/src/static/bootstrap4-toggle.min.js @@ -0,0 +1 @@ +!function(a){"use strict";function l(t,e){this.$element=a(t),this.options=a.extend({},this.defaults(),e),this.render()}l.VERSION="3.6.0",l.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"light",size:"normal",style:"",width:null,height:null},l.prototype.defaults=function(){return{on:this.$element.attr("data-on")||l.DEFAULTS.on,off:this.$element.attr("data-off")||l.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||l.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||l.DEFAULTS.offstyle,size:this.$element.attr("data-size")||l.DEFAULTS.size,style:this.$element.attr("data-style")||l.DEFAULTS.style,width:this.$element.attr("data-width")||l.DEFAULTS.width,height:this.$element.attr("data-height")||l.DEFAULTS.height}},l.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var t="large"===this.options.size||"lg"===this.options.size?"btn-lg":"small"===this.options.size||"sm"===this.options.size?"btn-sm":"mini"===this.options.size||"xs"===this.options.size?"btn-xs":"",e=a('