from django.db import transaction from .models import * from .selectors import * @transaction.atomic def create_wireguard_vpn(owner, public_key, network_mask): pool = get_suitable_pools(network_mask)[0] count = pool.wireguardvpn_set.count() # First object if count == 0: return WireGuardVPN.objects.create(owner=owner, vpnpool=pool, pool_index=0, wireguard_public_key=public_key) else: # Select last network and try +1 it last_net = WireGuardVPN.objects.filter(vpnpool=pool).order_by('pool_index').last() next_index = last_net.pool_index + 1 if next_index <= pool.max_pool_index: return WireGuardVPN.objects.create(owner=owner, vpnpool=pool, pool_index=next_index, wireguard_public_key=public_key) # Still there? Then we need to lookup previously used networks try: free_lease = WireGuardVPNFreeLeases.objects.get(vpnpool=pool) vpn = WireGuardVPN.objects.create(owner=owner, vpnpool=pool, pool_index=free_lease.pool_index, wireguard_public_key=public_key) free_lease.delete() return vpn except WireGuardVPNFreeLeases.DoesNotExist: pass @property def wireguard_config_filename(self): return '/etc/wireguard/{}.conf'.format(self.network) @property def wireguard_config(self): wireguard_config = [ """ [Interface] ListenPort = 51820 PrivateKey = {privatekey} """.format(privatekey=self.wireguard_private_key) ] peers = [] for reservation in self.vpnnetworkreservation_set.filter(status='used'): public_key = reservation.vpnnetwork_set.first().wireguard_public_key peer_network = "{}/{}".format(reservation.address, self.subnetwork_size) owner = reservation.vpnnetwork_set.first().owner peers.append(""" # Owner: {owner} [Peer] PublicKey = {public_key} AllowedIPs = {peer_network} """.format( owner=owner, public_key=public_key, peer_network=peer_network)) wireguard_config.extend(peers) return "\n".join(wireguard_config) def configure_wireguard_vpnserver(self): """ This method is designed to run as a celery task and should not be called directly from the web """ # subprocess, ssh pass def num_maximum_networks(self): """ sample: network_size = 40 subnetwork_size = 48 maximum_networks = 2^(48-40) 2nd sample: network_size = 8 subnetwork_size = 24 maximum_networks = 2^(24-8) """ return 2**(self.subnetwork_mask - self.network_mask)