[vpn] make a vpn creat-able!

[15:40] line:~% http -a nicoschottelius:$(pass ungleich.ch/nico.schottelius@ungleich.ch)  http://localhost:8000/net/vpn/ network_size=48  wireguard_public_key=$(wg genkey | wg pubkey)
HTTP/1.1 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Length: 206
Content-Type: application/json
Date: Sun, 12 Apr 2020 13:40:26 GMT
Server: WSGIServer/0.2 CPython/3.7.3
Vary: Accept
X-Content-Type-Options: nosniff
X-Frame-Options: DENY

{
    "extra_data": null,
    "network": "2a0a:e5c1:203::",
    "order": null,
    "owner": 30,
    "status": "PENDING",
    "uuid": "8f977a8f-e06a-4346-94ae-8f525df58b7b",
    "wireguard_public_key": "JvCuUTZHm9unasJkGsLKN0Bf/hu6ZSIv7dnIGPyJ6xA="
}
This commit is contained in:
Nico Schottelius 2020-04-12 15:40:39 +02:00
commit 85b4d70592
4 changed files with 100 additions and 50 deletions

View file

@ -19,7 +19,8 @@ class VPNNetworkSerializer(serializers.ModelSerializer):
# This is required for finding the VPN pool, but does not
# exist in the model
network_size = serializers.IntegerField(min_value=0,
max_value=128)
max_value=128,
write_only=True)
def validate_wireguard_public_key(self, value):
msg = _("Supplied key is not a valid wireguard public key")
@ -58,18 +59,37 @@ class VPNNetworkSerializer(serializers.ModelSerializer):
"""
Creating a new vpnnetwork - there are a couple of race conditions,
especially when run in parallel.
"""
pools = VPNPool.objects.filter(subnetwork_size=data['network_size'])
found_pool = False
What we should be doing:
- create a reservation race free
- map the reservation to a network (?)
"""
pools = VPNPool.objects.filter(subnetwork_size=validated_data['network_size'])
vpn_network = None
for pool in pools:
if pool.num_free_networks > 0:
found_pool = True
# address = pool.
# reservation = VPNNetworkReservation(vpnpool=pool,
next_address = pool.next_free_network
reservation, created = VPNNetworkReservation.objects.update_or_create(
vpnpool=pool, address=next_address,
defaults = {
'status': 'used'
})
vpn_network = VPNNetwork.objects.create(
owner=self.context['request'].user,
network=reservation,
wireguard_public_key=validated_data['wireguard_public_key']
)
break
if not vpn_network:
# FIXME: use correct exception
raise Exception("Did not find any free pool")
pool = VPNPool.objects.first(subnetwork_size=data['network_size'])
return VPNNetwork(**validated_data)
return vpn_network