add creating peerings (inside serverside config)

this doesn't actually add the peerings just saves the parameters to disk
This commit is contained in:
lare 2022-11-25 21:43:28 +01:00
parent 2c9cac02e0
commit b58690a620
3 changed files with 74 additions and 35 deletions

10
nodes/main.py Normal file
View file

@ -0,0 +1,10 @@
import falcon, json
class CompaniesResource(object):
companies = [{"id": 1, "name": "Company One"}, {"id": 2, "name": "Company Two"}]
def on_get(self, req, resp):
resp.body = json.dumps(self.companies)
api = falcon.API()
companies_endpoint = CompaniesResource()
api.add_route('/companies', companies_endpoint)

View file

@ -2,7 +2,7 @@
from flask import Flask, Response, redirect, render_template, request, session, abort from flask import Flask, Response, redirect, render_template, request, session, abort
import werkzeug.exceptions as werkzeug_exceptions import werkzeug.exceptions as werkzeug_exceptions
import json, os, base64, logging import json, os, base64, logging, random
from functools import wraps from functools import wraps
from ipaddress import ip_address, ip_network from ipaddress import ip_address, ip_network
import kioubit_verify import kioubit_verify
@ -50,51 +50,79 @@ class Config (dict):
self._config["peering-data"] = "./peerings" self._config["peering-data"] = "./peerings"
logging.info(self._config) logging.info(self._config)
class PeeringManager(dict): class PeeringManager:
def __init__(self, peering_dir): def __init__(self, peering_dir):
self._peering_dir = peering_dir self._peering_dir = peering_dir
self._load_peerings() self._load_peerings()
self.keys = self._peerings
def __contains__(self, o):
return self._peerings.__contains__(o)
def __getitem__(self, k):
return self._peerings[k]
def __setitem__(self, k, v):
pass
def __delitem__(self, v):
pass
def _load_peerings(self): def _load_peerings(self):
if not os.path.exists(self._peering_dir): if not os.path.exists(self._peering_dir):
os.mkdir(self._peering_dir) os.mkdir(self._peering_dir)
if not os.path.exists(f"{self._peering_dir}/peerings.json"): if not os.path.exists(f"{self._peering_dir}/peerings.json"):
with open(f"{self._peering_dir}/peerings.json", "x") as p: with open(f"{self._peering_dir}/peerings.json", "x") as p:
json.dump([], p) json.dump({"mnter":{},"asn":{}}, p)
with open(f"{self._peering_dir}/peerings.json","r") as p: try:
self._peerings = json.load(p) with open(f"{self._peering_dir}/peerings.json","r") as p:
self.peerings = {} self.peerings = json.load(p)
missing_peerings = False except json.decoder.JSONDecodeError:
for peering in self._peerings: with open(f"{self._peering_dir}/peerings.json", "w") as p:
if os.path.exists(f"{self._peering_dir}/{peering}.json"): json.dump({"mnter":{},"asn":{}}, p)
with open(f"{self._peering_dir}/{peering}.json") as peer_cfg: with open(f"{self._peering_dir}/peerings.json","r") as p:
self.peerings[peering] = json.load(peer_cfg) self.peerings = json.load(p)
else:
logging.warning(f"peering with id {peering} doesn't exist. removing reference in `{self._peering_dir}/peerings.json`") # self.peerings = {}
self._peerings.remove(peering) # missing_peerings = False
missing_peerings = True # for peering in self._peerings:
if missing_peerings: # if os.path.exists(f"{self._peering_dir}/{peering}.json"):
with open(f"{self._peering_dir}/peerings.json","w") as p: # with open(f"{self._peering_dir}/{peering}.json") as peer_cfg:
json.dump(self._peerings, p, indent=4) # self.peerings[peering] = json.load(peer_cfg)
# else:
# logging.warning(f"peering with id {peering} doesn't exist. removing reference in `{self._peering_dir}/peerings.json`")
# self._peerings.remove(peering)
# missing_peerings = True
# if missing_peerings:
# with open(f"{self._peering_dir}/peerings.json","w") as p:
# json.dump(self._peerings, p, indent=4)
def _save_peerings(self):
with open(f"{self._peering_dir}/peerings.json", "w") as p:
json.dump(self.peerings, p, indent=4)
def get_peerings_by_mnt(self, mnt): def get_peerings_by_mnt(self, mnt):
return [{}] # print(self.peerings)
raise NotImplementedError() try:
out = []
for asn in self.peerings["mnter"][mnt]:
try:
for peering in self.peerings["asn"][asn]:
out.append(peering)
except KeyError as e:
pass
return out
except KeyError:
return {}
def add_peering(self, mnt, asn, node, wg_key, endpoint=None, ipv6ll=None, ipv4=None, ipv6=None):
try:
if not asn in self.peerings["mnter"][mnt]:
self.peerings[mnt].append(asn)
except KeyError:
self.peerings["mnter"][mnt] = [asn]
try:
if not asn in self.peerings["asn"]:
self.peerings["asn"][asn] = []
except KeyError:
self.peerings["asn"][asn] = []
# deny more than one peering per ASN to one node
for peering in self.peerings["asn"][asn]:
if peering["node"] == node: return False
self.peerings["asn"][asn].append({"MNT":mnt,"ASN":asn, "node": node, "wg_key":wg_key, "endpoint": endpoint,"ipv6ll":ipv6ll,"ipv4":ipv4,"ipv6":ipv6})
self._save_peerings()
return True
config = Config() config = Config()
peerings = PeeringManager(config["peering-dir"]) peerings = PeeringManager(config["peering-dir"])
@ -205,6 +233,7 @@ def peerings_new():
## check if all required (and enabled) options are specified ## check if all required (and enabled) options are specified
try: try:
new_peering["peer-asn"] = session["user-data"]["asn"]
new_peering["peer-wgkey"] = request.form["peer-wgkey"] new_peering["peer-wgkey"] = request.form["peer-wgkey"]
if request.form["peer-endpoint-enabled"] == "on": if request.form["peer-endpoint-enabled"] == "on":
new_peering["peer-endpoint"] = request.form["peer-endpoint"] new_peering["peer-endpoint"] = request.form["peer-endpoint"]
@ -286,7 +315,7 @@ def peerings_new():
except ValueError: except ValueError:
return render_template("peerings-new.html", session=session,config=config, peerings=peerings, msg="invalid ip address(es) supplied"), 400 return render_template("peerings-new.html", session=session,config=config, peerings=peerings, msg="invalid ip address(es) supplied"), 400
peerings.add_peering(session["user-data"]["mnt"], session["user-data"]["asn"], request.args["node"], new_peering["peer-wgkey"], new_peering["peer-endpoint"], new_peering["peer-v6ll"], new_peering["peer-v4"], new_peering["peer-v6"])
return """<div>creating peerings is not (yet) implemented</div><div><a href="../">return</a>""" return """<div>creating peerings is not (yet) implemented</div><div><a href="../">return</a>"""
return f"{request.method} /peerings/new {str(request.args)}{str(request.form)}" return f"{request.method} /peerings/new {str(request.args)}{str(request.form)}"

View file

@ -8,7 +8,7 @@
<link rel="stylesheet" href="{{config['base-dir']}}static/style.css"> <link rel="stylesheet" href="{{config['base-dir']}}static/style.css">
</head> </head>
<body> <body>
<header class="flex flex-row"><div></div><a href="{{config['base-dir']}}">{{config["MNT"]}} Autopeering</a>{% if "login" in session %}<a href="{{config['base-dir']}}logout">logout</a>{% else %} <a href="{{config['base-dir']}}login?return=/peerings">login</a>{%endif%}</header> <header class="flex flex-row"><div></div><a href="{{config['base-dir']}}">{{config["MNT"]}} Autopeering</a>{% if "login" in session %} <div><a href="{{config['base-dir']}}peerings">manage</a> <a href="{{config['base-dir']}}logout">logout</a></div>{% else %} <a href="{{config['base-dir']}}login?return=/peerings">login</a>{%endif%}</header>
<div class="content flex"> <div class="content flex">
{% block content %} {% block content %}
{% endblock %} {% endblock %}