++vpn network

This commit is contained in:
Nico Schottelius 2020-12-13 13:28:43 +01:00
parent 5716cae900
commit cf948b03a8
7 changed files with 65 additions and 62 deletions

View file

@ -41,10 +41,6 @@ router.register(r'v1/service/matrix', serviceviews.MatrixServiceProductViewSet,
router.register(r'v1/service/generic', serviceviews.GenericServiceProductViewSet, basename='genericserviceproduct')
# Net
#router.register(r'v1/net/vpn', netviews.VPNNetworkViewSet, basename='vpnnetwork')
#router.register(r'v1/admin/vpnreservation', netviews.VPNNetworkReservationViewSet, basename='vpnnetreservation')
# Pay
router.register(r'v1/my/address', payviews.BillingAddressViewSet, basename='billingaddress')
@ -67,9 +63,18 @@ router.register(r'v1/my/user', authviews.UserViewSet, basename='user')
router.register(r'v1/admin/user', authviews.AdminUserViewSet, basename='useradmin')
router.register(r'v1/user/register', authviews.AccountManagementViewSet, basename='user/register')
################################################################################
# v2
# Net
router.register(r'v2/net/wireguardvpn', netviews.WireGuardVPNViewSet, basename='wireguardvpnnetwork')
#router.register(r'v1/admin/vpnreservation', netviews.VPNNetworkReservationViewSet, basename='vpnnetreservation')
urlpatterns = [
path(r'api/', include(router.urls)),
# web/ = stuff to view in the browser
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), # for login to REST API
path('openapi', get_schema_view(
@ -77,7 +82,9 @@ urlpatterns = [
description="uncloud API",
version="1.0.0"
), name='openapi-schema'),
path('vpn/create/', netviews.WireGuardVPNCreateView.as_view(), name="vpncreate"),
# web/ = stuff to view in the browser
# path('web/vpn/create/', netviews.WireGuardVPNCreateView.as_view(), name="vpncreate"),
path('login/', authviews.LoginView.as_view(), name="login"),
path('logout/', authviews.LogoutView.as_view(), name="logout"),

View file

@ -8,5 +8,4 @@ class WireGuardVPNForm(forms.ModelForm):
class Meta:
model = WireGuardVPN
fields = [ "wireguard_public_key" ]

View file

@ -29,6 +29,8 @@ class WireGuardVPN(models.Model):
"""
Created VPNNetworks
"""
owner = models.ForeignKey(get_user_model(),
on_delete=models.CASCADE)
vpnpool = models.ForeignKey(WireGuardVPNPool,
on_delete=models.CASCADE)

View file

@ -39,4 +39,6 @@ def allowed_vpn_network_reservation_size():
max_reservations=2**(F('subnetwork_mask')-F('network_mask'))).filter(
num_reservations__lt=F('max_reservations'))
return set([ pool.subnetwork_mask for pool in pools ])
# Need to return set of tuples, see
# https://docs.djangoproject.com/en/3.1/ref/models/fields/#field-choices
return set([ (pool.subnetwork_mask, pool.subnetwork_mask) for pool in pools ])

View file

@ -5,6 +5,16 @@ from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from .models import *
from .services import *
class WireGuardVPNSerializer(serializers.ModelSerializer):
class Meta:
model = WireGuardVPN
fields = [ 'wireguard_public_key' ]
read_only_fields = [ 'address ' ]
def create(self, validated_data):
pass
# class WireGuardVPNPoolSerializer(serializers.ModelSerializer):
# class Meta:

View file

@ -1,59 +1,35 @@
from django.db import transaction
from .models import *
from .selectors import *
@transaction.atomic
def create_vpn(*,
def create_wireguard_vpn(*,
public_key: str,
network_size: int
) -> VPNNetwork:
network_mask: int
) -> WireGuardVPN:
# Select suitable pool
pools = VPNPool.objects.filter(subnetwork_size=network_size)
pool = get_suitable_pool(network_mask)[0]
# FIXME: exception - which?
if not pools:
return None
# last_net = ipaddress.ip_network(self.used_networks.last().address)
# last_net_ip = last_net[0]
# Find all pools with the correct size
# if last_net_ip.version == 6:
# offset_to_next = 2**(128 - self.subnetwork_size)
# elif last_net_ip.version == 4:
# offset_to_next = 2**(32 - self.subnetwork_size)
# For each pool see if it has still space:
# num network reversations < 2**(subnetwork_size-network_size)
# next_net_ip = last_net_ip + offset_to_next
def next_free_network(self):
if self.num_free_networks == 0:
# FIXME: use right exception
raise Exception("No free networks")
if len(self.free_networks) > 0:
return self.free_networks[0].address
if len(self.used_networks) > 0:
"""
sample:
pool = 2a0a:e5c1:200::/40
last_used = 2a0a:e5c1:204::/48
next:
"""
last_net = ipaddress.ip_network(self.used_networks.last().address)
last_net_ip = last_net[0]
if last_net_ip.version == 6:
offset_to_next = 2**(128 - self.subnetwork_size)
elif last_net_ip.version == 4:
offset_to_next = 2**(32 - self.subnetwork_size)
next_net_ip = last_net_ip + offset_to_next
return str(next_net_ip)
else:
# first network to be created
return self.network
# return str(next_net_ip)
# else:
# # first network to be created
# return self.network
@property
def wireguard_config_filename(self):

View file

@ -23,17 +23,17 @@ from .forms import *
# queryset = VPNNetworkReservation.objects.all()
# class VPNNetworkViewSet(viewsets.ModelViewSet):
# serializer_class = VPNNetworkSerializer
# permission_classes = [permissions.IsAuthenticated]
class WireGuardVPNViewSet(viewsets.ModelViewSet):
serializer_class = WireGuardVPNSerializer
permission_classes = [permissions.IsAuthenticated]
# def get_queryset(self):
# if self.request.user.is_superuser:
# obj = VPNNetwork.objects.all()
# else:
# obj = VPNNetwork.objects.filter(owner=self.request.user)
def get_queryset(self):
if self.request.user.is_superuser:
obj = WireGuardVPN.objects.all()
else:
obj = WireGuardVPN.objects.filter(owner=self.request.user)
# return obj
return obj
class WireGuardVPNCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
@ -49,7 +49,14 @@ class WireGuardVPNCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView
return self.success_message % dict(cleaned_data,
the_prefix = self.object.prefix)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['available_sizes'] = 2
return context
# def get_context_data(self, **kwargs):
# context = super().get_context_data(**kwargs)
# context['available_sizes'] = 2
# return context
# def post(request, *args, **kwargs):
# print(request)
# print(*args)
# print(*kwargs)
# def post(self, request, *args, **kwargs):