1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-11-23 07:30:11 +01:00

Updated documentation, minor fixes

This commit is contained in:
theonlynexus 2022-07-20 15:25:01 +09:00
parent 305c23190c
commit 9e16619e56
9 changed files with 713 additions and 583 deletions

View File

@ -286,9 +286,9 @@ def update_peer_default_config():
config = g.conf config = g.conf
if ( if (
len(request.form["peer_endpoint_allowed_ips"]) == 0 not (request.form["peer_endpoint_allowed_ips"])
or len(request.form["peer_global_DNS"]) == 0 or not (request.form["peer_global_DNS"])
or len(request.form["peer_remote_endpoint"]) == 0 or not (request.form["peer_remote_endpoint"])
): ):
session["message"] = "Please fill in all required boxes." session["message"] = "Please fill in all required boxes."
session["message_status"] = "danger" session["message_status"] = "danger"

View File

@ -3,7 +3,10 @@ from __main__ import app
import sqlite3 import sqlite3
def get_net_stats(interface_name: str) -> list: def get_net_stats(interface_name: str) -> list[sqlite3.Row]:
"""
Gets net stats for all peers of `interface_name` and returns a list of dicts
"""
app.logger.debug(f"db.get_net_stats({interface_name})") app.logger.debug(f"db.get_net_stats({interface_name})")
data = g.cur.execute( data = g.cur.execute(
f"SELECT total_sent, total_receive, cumu_sent, cumu_receive FROM {interface_name}" f"SELECT total_sent, total_receive, cumu_sent, cumu_receive FROM {interface_name}"
@ -12,6 +15,9 @@ def get_net_stats(interface_name: str) -> list:
def get_net_stats_and_peer_status(interface_name: str, id: str) -> sqlite3.Row | None: def get_net_stats_and_peer_status(interface_name: str, id: str) -> sqlite3.Row | None:
"""
Gets net stats for a given peer of `interface_name` and the data as `dict`, `None` if not found.
"""
app.logger.debug(f"db.get_net_stats_and_peer_status({interface_name})") app.logger.debug(f"db.get_net_stats_and_peer_status({interface_name})")
data = g.cur.execute( data = g.cur.execute(
"""SELECT total_receive, total_sent, cumu_receive, cumu_sent, status """SELECT total_receive, total_sent, cumu_receive, cumu_sent, status
@ -21,7 +27,12 @@ def get_net_stats_and_peer_status(interface_name: str, id: str) -> sqlite3.Row |
return data.fetchone() return data.fetchone()
def get_peer_count_by_allowed_ips(interface_name: str, ip: str, id: str): def get_peer_count_by_allowed_ips(
interface_name: str, ip: str, id: str
) -> sqlite3.Row | None:
"""
Gets and returns the number of peers of `interface_name` that have allowed_ips similar to `ip`.
"""
app.logger.debug(f"db.get_peer_count_by_allowed_ips({interface_name}, {ip}, {id})") app.logger.debug(f"db.get_peer_count_by_allowed_ips({interface_name}, {ip}, {id})")
data = g.cur.execute( data = g.cur.execute(
f"""SELECT COUNT(*) FROM {interface_name} f"""SELECT COUNT(*) FROM {interface_name}
@ -31,7 +42,7 @@ def get_peer_count_by_allowed_ips(interface_name: str, ip: str, id: str):
return data.fetchone() return data.fetchone()
def get_peers(interface_name: str, search: str = None) -> list: def get_peers(interface_name: str, search: str = None) -> list[sqlite3.Row]:
"""Returns the list of records which name matches the search string, or all if no search is provided""" """Returns the list of records which name matches the search string, or all if no search is provided"""
app.logger.debug(f"db.get_peers({interface_name}, {search})") app.logger.debug(f"db.get_peers({interface_name}, {search})")
@ -44,8 +55,10 @@ def get_peers(interface_name: str, search: str = None) -> list:
return data.fetchall() return data.fetchall()
def get_peer_by_id(interface_name: str, id: str) -> list: def get_peer_by_id(interface_name: str, id: str) -> sqlite3.Row | None:
"""Returns the record matching the pass id or None.""" """
Returns the peer of `interface_name` matching `id` or None.
"""
app.logger.debug(f"db.get_peer_by_id({interface_name}, {id})") app.logger.debug(f"db.get_peer_by_id({interface_name}, {id})")
sql = "SELECT * FROM %s WHERE id='%s'" % (interface_name, id) sql = "SELECT * FROM %s WHERE id='%s'" % (interface_name, id)
@ -53,21 +66,29 @@ def get_peer_by_id(interface_name: str, id: str) -> list:
return data.fetchone() return data.fetchone()
def get_peer_allowed_ips(interface_name: str) -> list: def get_peer_allowed_ips(interface_name: str) -> list[sqlite3.Row]:
"""
Returns the `allowed_ips` of all peers of `interface_name`.
"""
app.logger.debug(f"db.get_peer_allowed_ips({interface_name})") app.logger.debug(f"db.get_peer_allowed_ips({interface_name})")
sql = f"SELECT allowed_ips FROM {interface_name}" sql = f"SELECT allowed_ips FROM {interface_name}"
data = g.cur.execute(sql) data = g.cur.execute(sql)
return data.fetchall() return data.fetchall()
def get_peer_ids(interface_name: str): def get_peer_ids(interface_name: str) -> list[sqlite3.Row]:
"""
Returns the `id`s of all peers of `interface_name`.
"""
app.logger.debug(f"db.get_peer_ids({interface_name})") app.logger.debug(f"db.get_peer_ids({interface_name})")
data = g.cur.execute("SELECT id FROM %s" % interface_name) data = g.cur.execute("SELECT id FROM %s" % interface_name)
return data.fetchall() return data.fetchall()
def remove_stale_peers(interface_name: str, peer_data: str): def remove_stale_peers(interface_name: str, peer_data: dict):
"""Removes entries that which id is present in the db, but not in peer_data""" """
Removes from the DB entries that are present there, but not in `peer_data`
"""
app.logger.debug(f"db.remove_stale_peers({interface_name}, peer_data)") app.logger.debug(f"db.remove_stale_peers({interface_name}, peer_data)")
db_key = set(map(lambda a: a[0], get_peer_ids(interface_name))) db_key = set(map(lambda a: a[0], get_peer_ids(interface_name)))
@ -79,12 +100,18 @@ def remove_stale_peers(interface_name: str, peer_data: str):
def delete_peer(interface_name: str, id: str): def delete_peer(interface_name: str, id: str):
"""
Removes a peer of `interface_name` with the given `id`
"""
app.logger.debug(f"db.delete_peer({interface_name}, {id})") app.logger.debug(f"db.delete_peer({interface_name}, {id})")
sql = "DELETE FROM %s WHERE id = '%s'" % (interface_name, id) sql = "DELETE FROM %s WHERE id = '%s'" % (interface_name, id)
g.cur.execute(sql) g.cur.execute(sql)
def insert_peer(interface_name: str, data: dict): def insert_peer(interface_name: str, data: dict):
"""
Inserts a peer of `interface_name` with the given `data`
"""
app.logger.debug(f"db.insert_peer({interface_name}, {data})") app.logger.debug(f"db.insert_peer({interface_name}, {data})")
sql = f""" sql = f"""
INSERT INTO {interface_name} INSERT INTO {interface_name}
@ -95,10 +122,13 @@ def insert_peer(interface_name: str, data: dict):
g.cur.execute(sql, data) g.cur.execute(sql, data)
def create_table_if_missing(table_name: str): def create_table_if_missing(interface_name: str):
app.logger.debug(f"db.create_table_if_missing({table_name})") """
Creates a table for `interface_name`, if missing.
"""
app.logger.debug(f"db.create_table_if_missing({interface_name})")
create_table = f""" create_table = f"""
CREATE TABLE IF NOT EXISTS {table_name} ( CREATE TABLE IF NOT EXISTS {interface_name} (
id VARCHAR NOT NULL PRIMARY KEY, private_key VARCHAR NULL UNIQUE, DNS VARCHAR NULL, id VARCHAR NOT NULL PRIMARY KEY, private_key VARCHAR NULL UNIQUE, DNS VARCHAR NULL,
endpoint_allowed_ips VARCHAR NULL, name VARCHAR NULL, total_receive FLOAT NULL, endpoint_allowed_ips VARCHAR NULL, name VARCHAR NULL, total_receive FLOAT NULL,
total_sent FLOAT NULL, total_data FLOAT NULL, endpoint VARCHAR NULL, total_sent FLOAT NULL, total_data FLOAT NULL, endpoint VARCHAR NULL,
@ -111,6 +141,9 @@ def create_table_if_missing(table_name: str):
def update_peer(interface_name: str, data: dict): def update_peer(interface_name: str, data: dict):
"""
Updates the peer of `interface_name` with the given `data`, if the peer record exists.
"""
app.logger.debug(f"db.interface_name({data})") app.logger.debug(f"db.interface_name({data})")
id = data["id"] id = data["id"]
db_peer = get_peer_by_id(interface_name, id) db_peer = get_peer_by_id(interface_name, id)
@ -121,6 +154,10 @@ def update_peer(interface_name: str, data: dict):
def _update_peer(interface_name: str, data: dict): def _update_peer(interface_name: str, data: dict):
"""
Updates the peer of `interface_name` with the given `data`.
`data` should contain the peer's `id` (public key), plus any other field to be updated.
"""
app.logger.debug(f"db.update_peer({interface_name}, {data})") app.logger.debug(f"db.update_peer({interface_name}, {data})")
sql = f""" sql = f"""
UPDATE {interface_name} SET UPDATE {interface_name} SET

View File

@ -322,7 +322,7 @@ def add_peer(interface_name):
data = request.get_json() data = request.get_json()
public_key = data["public_key"] public_key = data["public_key"]
allowed_ips = data["allowed_ips"] allowed_ips = data["allowed_ips"]
endpoint_allowed_ips = data["endpoint_allowed_ip"] endpoint_allowed_ips = data["endpoint_allowed_ips"]
dns_addresses = data["DNS"] dns_addresses = data["DNS"]
enable_preshared_key = data["enable_preshared_key"] enable_preshared_key = data["enable_preshared_key"]
preshared_key = data["preshared_key"] preshared_key = data["preshared_key"]
@ -398,7 +398,7 @@ def save_peer_setting(interface_name):
private_key = data["private_key"] private_key = data["private_key"]
dns_addresses = data["DNS"] dns_addresses = data["DNS"]
allowed_ips = data["allowed_ips"] allowed_ips = data["allowed_ips"]
endpoint_allowed_ips = data["endpoint_allowed_ip"] endpoint_allowed_ips = data["endpoint_allowed_ips"]
preshared_key = data["preshared_key"] preshared_key = data["preshared_key"]
db_peer = db.get_peer_by_id(interface_name, id) db_peer = db.get_peer_by_id(interface_name, id)
if db_peer: if db_peer:
@ -624,7 +624,7 @@ def add_peer_bulk(interface_name):
data = request.get_json() data = request.get_json()
keys = data["keys"] keys = data["keys"]
endpoint_allowed_ips = data["endpoint_allowed_ip"] endpoint_allowed_ips = data["endpoint_allowed_ips"]
dns_addresses = data["DNS"] dns_addresses = data["DNS"]
enable_preshared_key = data["enable_preshared_key"] enable_preshared_key = data["enable_preshared_key"]
amount = data["amount"] amount = data["amount"]

View File

@ -102,7 +102,7 @@
'</div>'; '</div>';
let peer_transfer = '<div class="col-12 peer_data_group" style="text-align: right; display: flex; margin-bottom: 0.5rem"><p class="text-primary" style="text-transform: uppercase; margin-bottom: 0; margin-right: 1rem"><small><i class="bi bi-arrow-down-right"></i> ' + roundN(peer.total_receive + total_r, 4) + ' GB</small></p> <p class="text-success" style="text-transform: uppercase; margin-bottom: 0"><small><i class="bi bi-arrow-up-right"></i> ' + roundN(peer.total_sent + total_s, 4) + ' GB</small></p> </div>'; let peer_transfer = '<div class="col-12 peer_data_group" style="text-align: right; display: flex; margin-bottom: 0.5rem"><p class="text-primary" style="text-transform: uppercase; margin-bottom: 0; margin-right: 1rem"><small><i class="bi bi-arrow-down-right"></i> ' + roundN(peer.total_receive + total_r, 4) + ' GB</small></p> <p class="text-success" style="text-transform: uppercase; margin-bottom: 0"><small><i class="bi bi-arrow-up-right"></i> ' + roundN(peer.total_sent + total_s, 4) + ' GB</small></p> </div>';
let peer_key = '<div class="col-sm"><small class="text-muted" style="display: flex"><strong>PEER</strong><strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong></small> <h6><samp class="ml-auto key">' + peer.id + '</samp></h6></div>'; let peer_key = '<div class="col-sm"><small class="text-muted" style="display: flex"><strong>PEER</strong><strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong></small> <h6><samp class="ml-auto key">' + peer.id + '</samp></h6></div>';
let peer_allowed_ip = '<div class="col-sm"><small class="text-muted"><strong>ALLOWED IP</strong></small><h6 style="text-transform: uppercase;">'+peer.allowed_ip+'</h6></div>'; let peer_allowed_ip = '<div class="col-sm"><small class="text-muted"><strong>ALLOWED IP</strong></small><h6 style="text-transform: uppercase;">' + peer.allowed_ips + '</h6></div>';
let peer_latest_handshake = '<div class="col-sm"> <small class="text-muted"><strong>LATEST HANDSHAKE</strong></small> <h6 style="text-transform: uppercase;">' + peer.latest_handshake + '</h6> </div>'; let peer_latest_handshake = '<div class="col-sm"> <small class="text-muted"><strong>LATEST HANDSHAKE</strong></small> <h6 style="text-transform: uppercase;">' + peer.latest_handshake + '</h6> </div>';
let peer_endpoint = '<div class="col-sm"><small class="text-muted"><strong>END POINT</strong></small><h6 style="text-transform: uppercase;">' + peer.endpoint + '</h6></div>'; let peer_endpoint = '<div class="col-sm"><small class="text-muted"><strong>END POINT</strong></small><h6 style="text-transform: uppercase;">' + peer.endpoint + '</h6></div>';
let peer_control = '<div class="col-sm"><hr><div class="button-group" style="display:flex"><button type="button" class="btn btn-outline-primary btn-setting-peer btn-control" id="' + peer.id + '" data-toggle="modal"><i class="bi bi-gear-fill" data-toggle="tooltip" data-placement="bottom" title="Peer Settings"></i></button> <button type="button" class="btn btn-outline-danger btn-delete-peer btn-control" id="' + peer.id + '" data-toggle="modal"><i class="bi bi-x-circle-fill" data-toggle="tooltip" data-placement="bottom" title="Delete Peer"></i></button>'; let peer_control = '<div class="col-sm"><hr><div class="button-group" style="display:flex"><button type="button" class="btn btn-outline-primary btn-setting-peer btn-control" id="' + peer.id + '" data-toggle="modal"><i class="bi bi-gear-fill" data-toggle="tooltip" data-placement="bottom" title="Peer Settings"></i></button> <button type="button" class="btn btn-outline-danger btn-delete-peer btn-control" id="' + peer.id + '" data-toggle="modal"><i class="bi bi-x-circle-fill" data-toggle="tooltip" data-placement="bottom" title="Delete Peer"></i></button>';
@ -169,7 +169,7 @@
}, },
data: JSON.stringify({ data: JSON.stringify({
"DNS": $new_add_DNS.val(), "DNS": $new_add_DNS.val(),
"endpoint_allowed_ip": $new_add_endpoint_allowed_ip.val(), "endpoint_allowed_ips": $new_add_endpoint_allowed_ip.val(),
"MTU": $new_add_MTU.val(), "MTU": $new_add_MTU.val(),
"keep_alive": $new_add_keep_alive.val(), "keep_alive": $new_add_keep_alive.val(),
"enable_preshared_key": $enable_preshare_key.prop("checked"), "enable_preshared_key": $enable_preshare_key.prop("checked"),
@ -649,7 +649,7 @@ $add_peer.addEventListener("click",function(){
"allowed_ips": $allowed_ips.val(), "allowed_ips": $allowed_ips.val(),
"name": $new_add_name.val(), "name": $new_add_name.val(),
"DNS": $new_add_DNS.val(), "DNS": $new_add_DNS.val(),
"endpoint_allowed_ip": $new_add_endpoint_allowed_ip.val(), "endpoint_allowed_ips": $new_add_endpoint_allowed_ip.val(),
"MTU": $new_add_MTU.val(), "MTU": $new_add_MTU.val(),
"keep_alive": $new_add_keep_alive.val(), "keep_alive": $new_add_keep_alive.val(),
"enable_preshared_key": $enable_preshare_key.prop("checked"), "enable_preshared_key": $enable_preshare_key.prop("checked"),
@ -867,10 +867,10 @@ $body.on("click", ".btn-setting-peer", function(){
$("#setting_modal #peer_name_textbox").val(response.name); $("#setting_modal #peer_name_textbox").val(response.name);
$("#setting_modal #peer_private_key_textbox").val(response.private_key); $("#setting_modal #peer_private_key_textbox").val(response.private_key);
$("#setting_modal #peer_DNS_textbox").val(response.DNS); $("#setting_modal #peer_DNS_textbox").val(response.DNS);
$("#setting_modal #peer_allowed_ip_textbox").val(response.allowed_ip); $("#setting_modal #peer_allowed_ip_textbox").val(response.allowed_ips);
$("#setting_modal #peer_endpoint_allowed_ips").val(response.endpoint_allowed_ip); $("#setting_modal #peer_endpoint_allowed_ips").val(response.endpoint_allowed_ips);
$("#setting_modal #peer_mtu").val(response.mtu); $("#setting_modal #peer_mtu").val(response.mtu);
$("#setting_modal #peer_keep_alive").val(response.keep_alive); $("#setting_modal #peer_keep_alive").val(response.keepalive);
$("#setting_modal #peer_preshared_key_textbox").val(response.preshared_key); $("#setting_modal #peer_preshared_key_textbox").val(response.preshared_key);
window.configurations.settingModal().toggle(); window.configurations.settingModal().toggle();
window.configurations.endProgressBar(); window.configurations.endProgressBar();
@ -941,8 +941,8 @@ $("#save_peer_setting").on("click",function (){
name: $peer_name_textbox.val(), name: $peer_name_textbox.val(),
DNS: $peer_DNS_textbox.val(), DNS: $peer_DNS_textbox.val(),
private_key: $peer_private_key_textbox.val(), private_key: $peer_private_key_textbox.val(),
allowed_ip: $peer_allowed_ip_textbox.val(), allowed_ips: $peer_allowed_ip_textbox.val(),
endpoint_allowed_ip: $peer_endpoint_allowed_ips.val(), endpoint_allowed_ips: $peer_endpoint_allowed_ips.val(),
MTU: $peer_mtu.val(), MTU: $peer_mtu.val(),
keep_alive: $peer_keep_alive.val(), keep_alive: $peer_keep_alive.val(),
preshared_key: $peer_preshared_key_textbox.val() preshared_key: $peer_preshared_key_textbox.val()

File diff suppressed because one or more lines are too long

View File

@ -3,6 +3,7 @@
{% with title=title%} {% with title=title%}
{% include "header.html"%} {% include "header.html"%}
{% endwith %} {% endwith %}
<body> <body>
<div class="no-response"> <div class="no-response">
<div class="container"> <div class="container">
@ -30,7 +31,8 @@
<div class="col"> <div class="col">
<small class="text-muted"><strong>SWITCH</strong></small><br> <small class="text-muted"><strong>SWITCH</strong></small><br>
<div id="conf_status_btn" class="info_loading"></div> <div id="conf_status_btn" class="info_loading"></div>
<div class="spinner-border text-primary" role="status" style="display: none; margin-top: 10px"> <div class="spinner-border text-primary" role="status"
style="display: none; margin-top: 10px">
<span class="sr-only">Loading...</span> <span class="sr-only">Loading...</span>
</div> </div>
</div> </div>
@ -49,7 +51,8 @@
</div> </div>
<div class="col-sm"> <div class="col-sm">
<small class="text-muted"><strong>TOTAL RECEIVED</strong></small> <small class="text-muted"><strong>TOTAL RECEIVED</strong></small>
<h6 style="text-transform: uppercase;" id="conf_total_data_received" class="info_loading"></h6> <h6 style="text-transform: uppercase;" id="conf_total_data_received" class="info_loading">
</h6>
</div> </div>
<div class="col-sm"> <div class="col-sm">
<small class="text-muted"><strong>TOTAL SENT</strong></small> <small class="text-muted"><strong>TOTAL SENT</strong></small>
@ -59,17 +62,20 @@
<div class="col-sm"> <div class="col-sm">
<small class="text-muted"> <small class="text-muted">
<strong>PUBLIC KEY</strong> <strong>PUBLIC KEY</strong>
<strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out" class="text-primary">CLICK TO COPY</strong> <strong style="margin-left: auto!important; opacity: 0; transition: 0.2s ease-in-out"
class="text-primary">CLICK TO COPY</strong>
</small> </small>
<h6 class="info_loading"><samp class="key" id="conf_public_key"></samp></h6> <h6 class="info_loading"><samp class="key" id="conf_public_key"></samp></h6>
</div> </div>
<div class="col-sm"> <div class="col-sm">
<small class="text-muted"><strong>LISTEN PORT</strong></small> <small class="text-muted"><strong>LISTEN PORT</strong></small>
<h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_listen_port"></samp></h6> <h6 style="text-transform: uppercase;" class="info_loading"><samp
id="conf_listen_port"></samp></h6>
</div> </div>
<div class="col-sm"> <div class="col-sm">
<small class="text-muted"><strong>ADDRESS</strong></small> <small class="text-muted"><strong>ADDRESS</strong></small>
<h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_address"></samp></h6> <h6 style="text-transform: uppercase;" class="info_loading"><samp id="conf_address"></samp>
</h6>
</div> </div>
</div> </div>
</div> </div>
@ -90,11 +96,22 @@
<div class="form-group"> <div class="form-group">
<label><small class="text-muted">Refresh Interval</small></label><br> <label><small class="text-muted">Refresh Interval</small></label><br>
<div class="btn-group interval-btn-group" role="group" style="width: 100%"> <div class="btn-group interval-btn-group" role="group" style="width: 100%">
<button style="width: 20%" type="button" class="btn btn-outline-primary btn-group-label refresh" data-toggle="tooltip" data-placement="bottom" title="Refresh Peers"><i class="bi bi-arrow-repeat"></i></button> <button style="width: 20%" type="button"
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="5000">5s</button> class="btn btn-outline-primary btn-group-label refresh" data-toggle="tooltip"
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="10000">10s</button> data-placement="bottom" title="Refresh Peers"><i
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="30000">30s</button> class="bi bi-arrow-repeat"></i></button>
<button style="width: 20%" type="button" class="btn btn-outline-primary update_interval" data-refresh-interval="60000">1m</button> <button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="5000">5s</button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="10000">10s</button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="30000">30s</button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary update_interval"
data-refresh-interval="60000">1m</button>
</div> </div>
</div> </div>
</div> </div>
@ -102,17 +119,26 @@
<div class="form-group"> <div class="form-group">
<label><small class="text-muted">Display Mode</small></label><br> <label><small class="text-muted">Display Mode</small></label><br>
<div class="btn-group display-btn-group" role="group" style="width: 100%"> <div class="btn-group display-btn-group" role="group" style="width: 100%">
<button style="width: 20%" type="button" class="btn btn-outline-primary display_mode" data-display-mode="grid"><i class="bi bi-grid-fill" style="font-size: 1.5rem;"></i></button> <button style="width: 20%" type="button"
<button style="width: 20%" type="button" class="btn btn-outline-primary display_mode" data-display-mode="list"><i class="bi bi-list" style="font-size: 1.5rem;"></i></button> class="btn btn-outline-primary display_mode" data-display-mode="grid"><i
class="bi bi-grid-fill" style="font-size: 1.5rem;"></i></button>
<button style="width: 20%" type="button"
class="btn btn-outline-primary display_mode" data-display-mode="list"><i
class="bi bi-list" style="font-size: 1.5rem;"></i></button>
</div> </div>
</div> </div>
</div> </div>
<div class="btn-manage-group"> <div class="btn-manage-group">
<button type="button" class="btn btn-primary add_btn"><i class="bi bi-plus-circle-fill" style=""></i></button> <button type="button" class="btn btn-primary add_btn"><i class="bi bi-plus-circle-fill"
<button type="button" class="btn btn-secondary setting_btn"><i class="bi bi-three-dots"></i></button> style=""></i></button>
<button type="button" class="btn btn-secondary setting_btn"><i
class="bi bi-three-dots"></i></button>
<div class="setting_btn_menu"> <div class="setting_btn_menu">
<a class="text-danger" id="delete_peers_by_bulk_btn"><i class="bi bi-trash-fill"></i> Delete Peers</a> <a class="text-danger" id="delete_peers_by_bulk_btn"><i class="bi bi-trash-fill"></i>
<a class="text-info" id="download_all_peers" data-url="/download_all/{{conf_data['name']}}"><i class="bi bi-cloud-download-fill"></i> Download All Peers</a> Delete Peers</a>
<a class="text-info" id="download_all_peers"
data-url="/download_all/{{conf_data['name']}}"><i
class="bi bi-cloud-download-fill"></i> Download All Peers</a>
</div> </div>
</div> </div>
@ -138,11 +164,15 @@
<div> <div>
<div class="custom-control custom-switch" style="margin-bottom: 1rem"> <div class="custom-control custom-switch" style="margin-bottom: 1rem">
<input class="custom-control-input" type="checkbox" id="bulk_add"> <input class="custom-control-input" type="checkbox" id="bulk_add">
<label class="custom-control-label" for="bulk_add"><strong>Add Peers by bulk</strong></label> <label class="custom-control-label" for="bulk_add"><strong>Add Peers by
<i class="bi bi-question-circle-fill" style="cursor: pointer" data-container="body" data-toggle="popover" data-placement="right" data-trigger="click" data-content="By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP."></i> bulk</strong></label>
<i class="bi bi-question-circle-fill" style="cursor: pointer" data-container="body"
data-toggle="popover" data-placement="right" data-trigger="click"
data-content="By adding peers by bulk, each peer's name will be auto generated, and Allowed IP will be assign to the next available IP."></i>
</div> </div>
<div class="form-group" style="margin: 0"> <div class="form-group" style="margin: 0">
<input type="number" class="form-control" id="new_add_amount" min="1" placeholder="Amount" disabled> <input type="number" class="form-control" id="new_add_amount" min="1" placeholder="Amount"
disabled>
<div id="bulk_amount_validation" class="invalid-feedback"></div> <div id="bulk_amount_validation" class="invalid-feedback"></div>
</div> </div>
@ -161,13 +191,16 @@
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" id="private_key" aria-describedby="private_key"> <input type="text" class="form-control" id="private_key" aria-describedby="private_key">
<div class="input-group-append"> <div class="input-group-append">
<button type="button" class="btn btn-danger" id="re_generate_key" data-toggle="tooltip" data-placement="top" title="Regenerate Key"><i class="bi bi-arrow-repeat"></i></button> <button type="button" class="btn btn-danger" id="re_generate_key"
data-toggle="tooltip" data-placement="top" title="Regenerate Key"><i
class="bi bi-arrow-repeat"></i></button>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group non-bulk"> <div class="form-group non-bulk">
<label for="public_key">Public Key <code>(Required)</code></label> <label for="public_key">Public Key <code>(Required)</code></label>
<input type="text" class="form-control" id="public_key" aria-describedby="public_key" disabled> <input type="text" class="form-control" id="public_key" aria-describedby="public_key"
disabled>
</div> </div>
<div class="row"> <div class="row">
<div class="col-sm-6 non-bulk"> <div class="col-sm-6 non-bulk">
@ -182,12 +215,14 @@
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control" id="allowed_ips"> <input type="text" class="form-control" id="allowed_ips">
<div class="input-group-append"> <div class="input-group-append">
<button type="button" class="btn btn-primary" id="search_available_ip" data-toggle="tooltip" data-placement="top" title="Search Available IPs"> <button type="button" class="btn btn-primary" id="search_available_ip"
data-toggle="tooltip" data-placement="top" title="Search Available IPs">
<i class="bi bi-search"></i> <i class="bi bi-search"></i>
</button> </button>
</div> </div>
</div> </div>
<p style="position: absolute; top: 4px; right: 1rem;" class="text-success" id="allowed_ips_indicator"></p> <p style="position: absolute; top: 4px; right: 1rem;" class="text-success"
id="allowed_ips_indicator"></p>
</div> </div>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
@ -198,8 +233,10 @@
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<div class="form-group"> <div class="form-group">
<label for="new_add_endpoint_allowed_ip">Endpoint Allowed IPs <code>(Required)</code></label> <label for="new_add_endpoint_allowed_ip">Endpoint Allowed IPs
<input type="text" class="form-control" id="new_add_endpoint_allowed_ip" value="{{ endpoint_allowed_ip }}"> <code>(Required)</code></label>
<input type="text" class="form-control" id="new_add_endpoint_allowed_ip"
value="{{ endpoint_allowed_ips }}">
</div> </div>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
@ -211,12 +248,14 @@
<div class="col-sm-6"> <div class="col-sm-6">
<div class="form-group"> <div class="form-group">
<label for="new_add_keep_alive">Persistent keepalive</label> <label for="new_add_keep_alive">Persistent keepalive</label>
<input type="text" class="form-control" id="new_add_keep_alive" value="{{ keep_alive }}"> <input type="text" class="form-control" id="new_add_keep_alive"
value="{{ keep_alive }}">
</div> </div>
</div> </div>
<div class="col-sm"> <div class="col-sm">
<div class="form-check"> <div class="form-check">
<input class="form-check-input" type="checkbox" id="enable_preshare_key" name="enable_preshare_key" value="enable_psk"> <input class="form-check-input" type="checkbox" id="enable_preshare_key"
name="enable_preshare_key" value="enable_psk">
<label class="form-check-label" for="enable_preshare_key">Use Pre-shared Key</label> <label class="form-check-label" for="enable_preshare_key">Use Pre-shared Key</label>
</div> </div>
</div> </div>
@ -225,7 +264,8 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="save_peer" conf_id={{conf_data['name']}}>Add</button> <button type="button" class="btn btn-primary" id="save_peer"
conf_id={{conf_data['name']}}>Add</button>
</div> </div>
</div> </div>
</div> </div>
@ -241,7 +281,8 @@
</button> </button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div id="remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert"> <div id="remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none"
role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
@ -250,7 +291,8 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">No</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">No</button>
<button type="button" class="btn btn-danger" id="delete_peer" conf_id={{conf_data['name']}} peer_id="">Yes</button> <button type="button" class="btn btn-danger" id="delete_peer" conf_id={{conf_data['name']}}
peer_id="">Yes</button>
</div> </div>
</div> </div>
</div> </div>
@ -266,14 +308,17 @@
</button> </button>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div id="setting_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert"> <div id="setting_peer_alert" class="alert alert-danger alert-dismissible fade show d-none"
role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
</div> </div>
<div class="mb-3"> <div class="mb-3">
<label for="peer_private_key_textbox" class="form-label">Private Key <code>(Required for QR Code and download)</code></label> <label for="peer_private_key_textbox" class="form-label">Private Key
<input type="password" class="form-control" id="peer_private_key_textbox" style="padding-right: 40px"> <code>(Required for QR Code and download)</code></label>
<input type="password" class="form-control" id="peer_private_key_textbox"
style="padding-right: 40px">
<a class="peer_private_key_textbox_switch"><i class="bi bi-eye-fill"></i></a> <a class="peer_private_key_textbox_switch"><i class="bi bi-eye-fill"></i></a>
</div> </div>
<div> <div>
@ -291,7 +336,8 @@
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<div class="mb-3"> <div class="mb-3">
<label for="peer_allowed_ip_textbox" class="form-label">Allowed IPs <code>(Required)</code></label> <label for="peer_allowed_ip_textbox" class="form-label">Allowed IPs
<code>(Required)</code></label>
<input type="text" class="form-control" id="peer_allowed_ip_textbox"> <input type="text" class="form-control" id="peer_allowed_ip_textbox">
</div> </div>
</div> </div>
@ -303,7 +349,8 @@
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<div class="mb-3"> <div class="mb-3">
<label for="peer_endpoint_allowed_ips" class="form-label">Endpoint Allowed IPs <code>(Required)</code></label> <label for="peer_endpoint_allowed_ips" class="form-label">Endpoint Allowed IPs
<code>(Required)</code></label>
<input type="text" class="form-control" id="peer_endpoint_allowed_ips"> <input type="text" class="form-control" id="peer_endpoint_allowed_ips">
</div> </div>
</div> </div>
@ -323,7 +370,8 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" id="save_peer_setting" conf_id={{conf_data['name']}} peer_id="">Save</button> <button type="button" class="btn btn-primary" id="save_peer_setting" conf_id={{conf_data['name']}}
peer_id="">Save</button>
</div> </div>
</div> </div>
</div> </div>
@ -360,7 +408,8 @@
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
</div> </div>
<div id="bulk_remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none" role="alert" style="margin: 1rem"> <div id="bulk_remove_peer_alert" class="alert alert-danger alert-dismissible fade show d-none"
role="alert" style="margin: 1rem">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span> <span aria-hidden="true">&times;</span>
</button> </button>
@ -373,8 +422,10 @@
<div class="list-group"></div> <div class="list-group"></div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<a class="text-danger" id="select_all_delete_bulk_peers" style="cursor: pointer; margin-right: auto;"><small><strong>SELECT ALL</strong></small></a> <a class="text-danger" id="select_all_delete_bulk_peers"
<button type="button" class="btn btn-danger" id="confirm_delete_bulk_peers" disabled data-conf="{{conf_data['name']}}">Delete</button> style="cursor: pointer; margin-right: auto;"><small><strong>SELECT ALL</strong></small></a>
<button type="button" class="btn btn-danger" id="confirm_delete_bulk_peers" disabled
data-conf="{{conf_data['name']}}">Delete</button>
</div> </div>
</div> </div>
</div> </div>
@ -423,4 +474,5 @@
configurations.loadPeers($('#search_peer_textbox').val()); configurations.loadPeers($('#search_peer_textbox').val());
}); });
</script> </script>
</html> </html>

View File

@ -3,6 +3,7 @@
{% set title="Settings" %} {% set title="Settings" %}
{% include "header.html" %} {% include "header.html" %}
{% endwith %} {% endwith %}
<body> <body>
{% include "navbar.html" %} {% include "navbar.html" %}
<div class="container-fluid"> <div class="container-fluid">
@ -26,32 +27,30 @@
<div class="col-sm-6"> <div class="col-sm-6">
<label for="peer_global_DNS">DNS</label> <label for="peer_global_DNS">DNS</label>
<input type="text" class="form-control mb-4" id="peer_global_DNS" <input type="text" class="form-control mb-4" id="peer_global_DNS"
name="peer_global_DNS" name="peer_global_DNS" value="{{ peer_global_DNS }}" required>
value="{{ peer_global_DNS }}" required>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="peer_endpoint_allowed_ip">Peer Endpoint Allowed IPs</label> <label for="peer_endpoint_allowed_ips">Peer Endpoint Allowed IPs</label>
<input type="text" class="form-control mb-4" id="peer_endpoint_allowed_ip" <input type="text" class="form-control mb-4" id="peer_endpoint_allowed_ip"
name="peer_endpoint_allowed_ip" name="peer_endpoint_allowed_ips" value="{{ peer_endpoint_allowed_ips }}"
value="{{ peer_endpoint_allowed_ip }}" required> required>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="peer_mtu">MTU</label> <label for="peer_mtu">MTU</label>
<input type="text" class="form-control mb-4" id="peer_mtu" <input type="text" class="form-control mb-4" id="peer_mtu" name="peer_mtu"
name="peer_mtu"
value="{{ peer_mtu }}"> value="{{ peer_mtu }}">
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">
<label for="peer_keep_alive">Persistent Keepalive</label> <label for="peer_keep_alive">Persistent Keepalive</label>
<input type="text" class="form-control mb-4" id="peer_keep_alive" <input type="text" class="form-control mb-4" id="peer_keep_alive"
name="peer_keep_alive" name="peer_keep_alive" value="{{ peer_keepalive }}">
value="{{ peer_keepalive }}">
</div> </div>
<div class="col-sm-12"> <div class="col-sm-12">
<label for="peer_remote_endpoint"><strong>Peer Remote Endpoint (This will be change globally, and will be apply to all peer's QR code and configuration file.)</strong></label> <label for="peer_remote_endpoint"><strong>Peer Remote Endpoint (This will be
change globally, and will be apply to all peer's QR code and
configuration file.)</strong></label>
<input type="text" class="form-control mb-4" id="peer_remote_endpoint" <input type="text" class="form-control mb-4" id="peer_remote_endpoint"
name="peer_remote_endpoint" name="peer_remote_endpoint" value="{{ peer_remote_endpoint }}" required>
value="{{ peer_remote_endpoint }}" required>
</div> </div>
</div> </div>
<button class="btn btn-success" type="submit">Update Peer Default Settings</button> <button class="btn btn-success" type="submit">Update Peer Default Settings</button>
@ -68,7 +67,8 @@
<label for="wg_conf_path">Path</label> <label for="wg_conf_path">Path</label>
<input type="text" class="form-control mb-2" id="wg_conf_path" name="wg_conf_path" <input type="text" class="form-control mb-2" id="wg_conf_path" name="wg_conf_path"
value="{{ wg_conf_path }}"> value="{{ wg_conf_path }}">
<p class="text-muted">Remember to remove <code>/</code> at the end of your path. e.g <code>/etc/wireguard</code> <p class="text-muted">Remember to remove <code>/</code> at the end of your path. e.g
<code>/etc/wireguard</code>
</p> </p>
<button class="btn btn-danger change_path">Update Path & Restart Dashboard</button> <button class="btn btn-danger change_path">Update Path & Restart Dashboard</button>
</div> </div>
@ -115,8 +115,10 @@
<div class="row"> <div class="row">
<div class="col-sm"> <div class="col-sm">
<label for="app_ip">Dashboard IP</label> <label for="app_ip">Dashboard IP</label>
<input type="text" class="form-control mb-2" id="app_ip" name="app_ip" value="{{ app_ip }}"> <input type="text" class="form-control mb-2" id="app_ip" name="app_ip"
<p><small class="text-danger mb-4">0.0.0.0 means it can be access by anyone with your server value="{{ app_ip }}">
<p><small class="text-danger mb-4">0.0.0.0 means it can be access by anyone with
your server
IP Address.</small></p> IP Address.</small></p>
</div> </div>
<div class="col-sm"> <div class="col-sm">
@ -153,8 +155,10 @@
<p class="app_new_port text-bold text-danger" style="font-weight: bold"></p> <p class="app_new_port text-bold text-danger" style="font-weight: bold"></p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary cancel_restart" data-dismiss="modal">Cancel</button> <button type="button" class="btn btn-secondary cancel_restart"
<button type="button" class="btn btn-danger confirm_restart">Confirm & Restart Dashboard</button> data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger confirm_restart">Confirm & Restart
Dashboard</button>
</div> </div>
</div> </div>
</div> </div>
@ -201,4 +205,5 @@
}); });
</script> </script>
</html> </html>

View File

@ -14,16 +14,21 @@ Helper Functions
""" """
def adapt_for_rest(x): def get_interface_file_path(interface_name: str, base_dir: str) -> str:
x["allowed_ip"] = x.pop("allowed_ips") return os.path.join(base_dir, f"{interface_name}.conf")
x["endpoint_allowed_ip"] = x.pop("endpoint_allowed_ips")
for i in ["latest_handshake", "endpoint", "allowed_ip"]:
if not x[i]:
x[i] = "N/A"
return x
def connect_db(dashboard_configuration_dir): def adapt_for_rest(peer_dict: dict) -> dict:
"""
Renames necessary entries and replaces falsy values. Returns the modified dict.
"""
for i in ["latest_handshake", "endpoint", "allowed_ips"]:
if not peer_dict[i]:
peer_dict[i] = "(None)"
return peer_dict
def connect_db(dashboard_configuration_dir: str):
""" """
Connect to the database Connect to the database
@return: sqlite3.Connection @return: sqlite3.Connection
@ -35,7 +40,7 @@ def connect_db(dashboard_configuration_dir):
return con return con
def read_dashboard_conf(dashboard_conf_file_path): def read_dashboard_conf(dashboard_conf_file_path: str):
""" """
Get dashboard configuration Get dashboard configuration
@return: configparser.ConfigParser @return: configparser.ConfigParser
@ -45,7 +50,7 @@ def read_dashboard_conf(dashboard_conf_file_path):
return r_config return r_config
def write_dashboard_conf(config, dashboard_conf_file_path): def write_dashboard_conf(config: str, dashboard_conf_file_path: str):
""" """
Write to configuration Write to configuration
@param config: Input configuration @param config: Input configuration
@ -54,7 +59,9 @@ def write_dashboard_conf(config, dashboard_conf_file_path):
config.write(conf_object) config.write(conf_object)
def wg_peer_data_to_db(interface_name, wg_conf_dir, dashboard_conf_file_path): def wg_peer_data_to_db(
interface_name: str, wg_conf_dir: str, dashboard_conf_file_path: str
):
""" """
Look for new peers from WireGuard Look for new peers from WireGuard
@param interface_name: Configuration name @param interface_name: Configuration name
@ -110,9 +117,7 @@ def wg_peer_data_to_db(interface_name, wg_conf_dir, dashboard_conf_file_path):
handshakes = wg.get_interface_peers_latest_handshakes(interface_name) handshakes = wg.get_interface_peers_latest_handshakes(interface_name)
transfers = wg.get_interface_peers_net_stats(interface_name) transfers = wg.get_interface_peers_net_stats(interface_name)
endpoints = wg.get_interface_peers_endpoints(interface_name) endpoints = wg.get_interface_peers_endpoints(interface_name)
allowed_ips = wg.get_interface_peers_allowed_ips( allowed_ips = wg.get_interface_peers_allowed_ips(interface_and_peer_data)
interface_and_peer_data, interface_name
)
keys = set() keys = set()
for x in [handshakes, transfers, endpoints, allowed_ips]: for x in [handshakes, transfers, endpoints, allowed_ips]:
keys.update(x.keys()) keys.update(x.keys())
@ -127,7 +132,11 @@ def wg_peer_data_to_db(interface_name, wg_conf_dir, dashboard_conf_file_path):
def update_db_and_get_peers( def update_db_and_get_peers(
interface_name, search, sort_t, wg_conf_dir, dashboard_conf_file_path interface_name: str,
search: str,
sort_t: str,
wg_conf_dir: str,
dashboard_conf_file_path: str,
): ):
""" """
Get all peers. Get all peers.
@ -162,7 +171,7 @@ def update_db_and_get_peers(
return result return result
def get_conf_list(wg_conf_dir): def get_conf_list(wg_conf_dir: str):
"""Get all wireguard interfaces with status. """Get all wireguard interfaces with status.
@return: Return a list of dicts with interfaces and its statuses @return: Return a list of dicts with interfaces and its statuses
@rtype: list @rtype: list
@ -188,7 +197,7 @@ def get_conf_list(wg_conf_dir):
return conf return conf
def f_check_key_match(private_key, public_key, interface_name): def f_check_key_match(private_key: str, public_key: str, interface_name: str):
""" """
Check if private key and public key match Check if private key and public key match
@param private_key: Private key @param private_key: Private key
@ -216,7 +225,7 @@ def f_check_key_match(private_key, public_key, interface_name):
return {"status": "success"} return {"status": "success"}
def check_repeat_allowed_ips(public_key, ip, interface_name): def check_repeat_allowed_ips(public_key: str, ip: str, interface_name: str):
""" """
Check if there are repeated IPs Check if there are repeated IPs
@param public_key: Public key of the peer @param public_key: Public key of the peer
@ -238,7 +247,7 @@ def check_repeat_allowed_ips(public_key, ip, interface_name):
return {"status": "success"} return {"status": "success"}
def f_available_ips(interface_name, wg_conf_dir): def f_available_ips(interface_name: str, wg_conf_dir: str):
""" """
Get a list of available IPs Get a list of available IPs
@param interface_name: Configuration Name @param interface_name: Configuration Name
@ -289,7 +298,7 @@ def ensure_subnet(ipv4: str, default_subnet: str = "24") -> str:
# Regex Match # Regex Match
def regex_match(regex, text): def regex_match(regex: str, text: str):
pattern = re.compile(regex) pattern = re.compile(regex)
return pattern.search(text) is not None return pattern.search(text) is not None

View File

@ -7,15 +7,21 @@ import db
import os import os
import ifcfg import ifcfg
import re import re
import util
def _is_comment_line(line: str) -> bool: def _is_comment_line(line: str) -> bool:
"""Returns true if the passed string is a comment""" """
Returns true if the passed string is a comment in an INI style file.
"""
line = line.strip() line = line.strip()
return line.startswith("#") or line.startswith(";") return line.startswith("#") or line.startswith(";")
def _parse_peer_or_interface(lines, i, limit): def _parse_peer_or_interface(lines: list[str], i: int, limit: int) -> dict:
"""
Parses a [Peer] or [Interface] section of an interface config file into a `dict`.
"""
data = {} data = {}
while i < limit: while i < limit:
line = lines[i].strip() line = lines[i].strip()
@ -30,23 +36,32 @@ def _parse_peer_or_interface(lines, i, limit):
def set_peer_options( def set_peer_options(
interface_name, public_key, allowed_ips, preshared_key_filename=None interface_name: str,
public_key: str,
allowed_ips: str,
preshared_key_filename: str = None,
): ):
"""
Sets the given options for the specified `interface_name` and peer (`public_key`)
"""
if preshared_key_filename: if preshared_key_filename:
status = subprocess.check_output( subprocess.check_output(
f"wg set {interface_name} peer {public_key} allowed-ips {allowed_ips} preshared-key {preshared_key_filename}", f"wg set {interface_name} peer {public_key} allowed-ips {allowed_ips} preshared-key {preshared_key_filename}",
shell=True, shell=True,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
) )
else: else:
status = subprocess.check_output( subprocess.check_output(
f"wg set {interface_name} peer {public_key} allowed-ips {allowed_ips}", f"wg set {interface_name} peer {public_key} allowed-ips {allowed_ips}",
shell=True, shell=True,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
) )
def remove_peer_from_interface(interface_name, public_key): def remove_peer_from_interface(interface_name: str, public_key: str):
"""
Removes the specified peer (`public_key`) from `interface_name`
"""
subprocess.check_output( subprocess.check_output(
f"wg set {interface_name} peer {public_key} remove", f"wg set {interface_name} peer {public_key} remove",
shell=True, shell=True,
@ -54,7 +69,7 @@ def remove_peer_from_interface(interface_name, public_key):
) )
def get_interface_listen_port(interface_name, base_dir): def get_interface_listen_port(interface_name: str, base_dir: str) -> str:
""" """
Get listen port number. Get listen port number.
@param interface_name: Name of WG interface @param interface_name: Name of WG interface
@ -80,7 +95,7 @@ def get_interface_listen_port(interface_name, base_dir):
return port return port
def get_interface_public_key(interface_name, base_dir): def get_interface_public_key(interface_name: str, base_dir: str) -> str:
""" """
Get public key for configuration. Get public key for configuration.
@param interface_name: Name of WG interface @param interface_name: Name of WG interface
@ -122,7 +137,7 @@ def get_interface_total_net_stats(interface_name):
return [total, upload_total, download_total] return [total, upload_total, download_total]
def get_interface_status(interface_name): def get_interface_status(interface_name: str) -> str:
""" """
Check if the configuration is running or not Check if the configuration is running or not
@param interface_name: @param interface_name:
@ -206,7 +221,7 @@ def read_interface_config_file(interface_name: str, base_dir: str) -> dict:
""" """
app.logger.debug(f"read_conf_file({interface_name})") app.logger.debug(f"read_conf_file({interface_name})")
config_file = os.path.join(base_dir, f"{interface_name}.conf") config_file = util.get_interface_file_path(interface_name, base_dir)
with open(config_file, "r", encoding="utf-8") as file_object: with open(config_file, "r", encoding="utf-8") as file_object:
file = list(file_object.readlines()) file = list(file_object.readlines())
result = {"Interface": {}, "Peers": []} result = {"Interface": {}, "Peers": []}
@ -229,7 +244,10 @@ def read_interface_config_file(interface_name: str, base_dir: str) -> dict:
def switch_interface(interface_name: str, base_dir: str): def switch_interface(interface_name: str, base_dir: str):
config_file = os.path.join(base_dir, f"{interface_name}.conf") """
Switches `interface_name` around (up if it is down, down if it is up)
"""
config_file = util.get_interface_file_path(interface_name, base_dir)
status = get_interface_status(interface_name) status = get_interface_status(interface_name)
if status == "running": if status == "running":
check = subprocess.check_output( check = subprocess.check_output(
@ -242,14 +260,20 @@ def switch_interface(interface_name: str, base_dir: str):
def enable_interface(interface_name: str, base_dir: str): def enable_interface(interface_name: str, base_dir: str):
config_file = os.path.join(base_dir, f"{interface_name}.conf") """
Brings `interface_name` up (enables it)
"""
config_file = util.get_interface_file_path(interface_name, base_dir)
check = subprocess.check_output( check = subprocess.check_output(
"wg-quick up " + config_file, shell=True, stderr=subprocess.STDOUT "wg-quick up " + config_file, shell=True, stderr=subprocess.STDOUT
) )
def disable_interface(interface_name: str, base_dir: str): def disable_interface(interface_name: str, base_dir: str):
config_file = os.path.join(base_dir, f"{interface_name}.conf") """
Brings `interface_name` down (disables it)
"""
config_file = util.get_interface_file_path(interface_name, base_dir)
check = subprocess.check_output( check = subprocess.check_output(
"wg-quick down " + config_file, shell=True, stderr=subprocess.STDOUT "wg-quick down " + config_file, shell=True, stderr=subprocess.STDOUT
) )
@ -297,7 +321,7 @@ def get_interface_peers_latest_handshakes(interface_name) -> dict:
return result return result
def get_interface_peers_net_stats(interface_name) -> dict: def get_interface_peers_net_stats(interface_name: str) -> dict:
""" """
Get transfer from all peers of a configuration Get transfer from all peers of a configuration
@param interface_name: Configuration name @param interface_name: Configuration name
@ -354,14 +378,17 @@ def get_interface_peers_net_stats(interface_name) -> dict:
return result return result
def quick_save_interface_config(interface_name, base_dir): def quick_save_interface_config(interface_name: str, base_dir: str):
config_file = os.path.join(base_dir, f"{interface_name}.conf") """
Executes `wg-quick save` for `interface_name`
"""
config_file = util.get_interface_file_path(interface_name, base_dir)
status = subprocess.check_output( status = subprocess.check_output(
"wg-quick save " + config_file, shell=True, stderr=subprocess.STDOUT "wg-quick save " + config_file, shell=True, stderr=subprocess.STDOUT
) )
def gen_public_key(private_key): def gen_public_key(private_key: str):
"""Generate the public key. """Generate the public key.
@param private_key: Private key @param private_key: Private key
@ -390,7 +417,7 @@ def gen_public_key(private_key):
} }
def get_interface_peers_endpoints(interface_name) -> dict: def get_interface_peers_endpoints(interface_name: str) -> dict:
""" """
Get endpoint from all peers of a configuration Get endpoint from all peers of a configuration
@param interface_name: Configuration name @param interface_name: Configuration name
@ -414,7 +441,7 @@ def get_interface_peers_endpoints(interface_name) -> dict:
return result return result
def get_interface_peers_allowed_ips(conf_peer_data, interface_name) -> dict: def get_interface_peers_allowed_ips(conf_peer_data: str) -> dict:
""" """
Get allowed ips from all peers of a configuration Get allowed ips from all peers of a configuration
@param conf_peer_data: Configuration peer data @param conf_peer_data: Configuration peer data