++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') 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 # Pay
router.register(r'v1/my/address', payviews.BillingAddressViewSet, basename='billingaddress') 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/admin/user', authviews.AdminUserViewSet, basename='useradmin')
router.register(r'v1/user/register', authviews.AccountManagementViewSet, basename='user/register') 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 = [ urlpatterns = [
path(r'api/', include(router.urls)), 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('api-auth/', include('rest_framework.urls', namespace='rest_framework')), # for login to REST API
path('openapi', get_schema_view( path('openapi', get_schema_view(
@ -77,7 +82,9 @@ urlpatterns = [
description="uncloud API", description="uncloud API",
version="1.0.0" version="1.0.0"
), name='openapi-schema'), ), 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('login/', authviews.LoginView.as_view(), name="login"),
path('logout/', authviews.LogoutView.as_view(), name="logout"), path('logout/', authviews.LogoutView.as_view(), name="logout"),

View file

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

View file

@ -29,6 +29,8 @@ class WireGuardVPN(models.Model):
""" """
Created VPNNetworks Created VPNNetworks
""" """
owner = models.ForeignKey(get_user_model(),
on_delete=models.CASCADE)
vpnpool = models.ForeignKey(WireGuardVPNPool, vpnpool = models.ForeignKey(WireGuardVPNPool,
on_delete=models.CASCADE) 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( max_reservations=2**(F('subnetwork_mask')-F('network_mask'))).filter(
num_reservations__lt=F('max_reservations')) 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 rest_framework import serializers
from .models import * 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 WireGuardVPNPoolSerializer(serializers.ModelSerializer):
# class Meta: # class Meta:

View file

@ -1,59 +1,35 @@
from django.db import transaction from django.db import transaction
from .models import * from .models import *
from .selectors import *
@transaction.atomic @transaction.atomic
def create_vpn(*, def create_wireguard_vpn(*,
public_key: str, public_key: str,
network_size: int network_mask: int
) -> VPNNetwork: ) -> WireGuardVPN:
# Select suitable pool pool = get_suitable_pool(network_mask)[0]
pools = VPNPool.objects.filter(subnetwork_size=network_size)
# FIXME: exception - which? # FIXME: exception - which?
if not pools: if not pools:
return None 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: # next_net_ip = last_net_ip + offset_to_next
# num network reversations < 2**(subnetwork_size-network_size)
# return str(next_net_ip)
def next_free_network(self): # else:
if self.num_free_networks == 0: # # first network to be created
# FIXME: use right exception # return self.network
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
@property @property
def wireguard_config_filename(self): def wireguard_config_filename(self):

View file

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