from django.db import transaction from .models import * from .selectors import * from .tasks import * from django_q.tasks import async_task, result @transaction.atomic def create_wireguard_vpn(owner, public_key, network_mask): # Check if the user has a membership. #------------------------------------ # If yes, user is eligible for API access and 2 VPNs # If user already has 2 VPNs, we deduct from the credit # If deduction is higher than the allowed credit, we fail # # Check if the user has suitable balance # Create order # return create_wireguard_vpn_tech(owner, public_key, network_mask) @transaction.atomic def create_wireguard_vpn_tech(owner, public_key, network_mask): pool = get_suitable_pools(network_mask)[0] count = pool.wireguardvpn_set.count() # Try re-using previously used networks first 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() except WireGuardVPNFreeLeases.DoesNotExist: # First object if count == 0: vpn = 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: vpn = WireGuardVPN.objects.create(owner=owner, vpnpool=pool, pool_index=next_index, wireguard_public_key=public_key) config = pool.wireguard_config server = pool.vpn_server_hostname wg_name = pool.wg_name async_task(configure_wireguard_server_on_host, (wg_name, config), queue=server) return vpn