diff --git a/uncloud_django_based/uncloud/doc/README.md b/uncloud_django_based/uncloud/doc/README.md index 390a3af..3bded7e 100644 --- a/uncloud_django_based/uncloud/doc/README.md +++ b/uncloud_django_based/uncloud/doc/README.md @@ -57,18 +57,11 @@ After postresql is started, apply the migrations: python manage.py migrate ``` -### Secrets - -cp `uncloud/secrets_sample.py` to `uncloud/secrets.py` and replace the -sample values with real values. - - ## Flows / Orders + ### Creating a VMHost - - ### Creating a VM * Create a VMHost @@ -93,3 +86,50 @@ http -a nicoschottelius:$(pass ungleich.ch/nico.schottelius@ungleich.ch) http:// ``` http -a nicoschottelius:$(pass ungleich.ch/nico.schottelius@ungleich.ch) http://localhost:8000/vm/snapshot/ vm_uuid=$(uuidgen) ``` + +## VPNs + +VPNs consist of VPNPools ("networks of networks") which are handled by +VPNHosts. Users can requests VPNs with specific sizes. + +VPNs support both IPv6 and IPv4. However only IPv6 support has not been + +### Managing VPNPools + +``` +http -a nico:$(pass ldap/nico) https://uncloud.place7.ungleich.ch/v1/admin/vpnpool/ network=2a0a:e5c1:200:: network_size=40 subnetwork_size=48 vpn_hostname=vpn-2a0ae5c1200.ungleich.ch wireguard_private_key=$(wg genkey) +``` + +This will create the VPNPool 2a0a:e5c1:200::/40 from which /48 +networks will be used for clients. + +VPNPools can only be managed by staff. + +### Managing VPNNetworks + + +To request a network as a client, use the following call: + +``` +http -a nicoschottelius:$(pass ungleich.ch/nico.schottelius@ungleich.ch)https://uncloud.place7.ungleich.ch/v1/net/vpn/ network_size=48 wireguard_public_key=$(wg genkey | tee privatekey | wg pubkey) +``` + +VPNNetworks can be managed by all authenticated users. + + +## Proposed (uncoded) flows + +### Changing the disk size of a VM + +* GET on ../vm/vm/ should list uuids of disks +* UPDATE on ../vm/disk/ with size=newsize + * Newsize > oldsize! +* Triggers shutdown of VM +* Resizes disk +* Starts VM +* Maybe confirm flag? + + +### Adding a disk to a VM + +(TBD) diff --git a/uncloud_django_based/uncloud/uncloud_net/models.py b/uncloud_django_based/uncloud/uncloud_net/models.py index e56b79c..b5a181e 100644 --- a/uncloud_django_based/uncloud/uncloud_net/models.py +++ b/uncloud_django_based/uncloud/uncloud_net/models.py @@ -173,6 +173,13 @@ class VPNNetwork(Product): wireguard_public_key = models.CharField(max_length=48) + default_recurring_period = RecurringPeriod.PER_YEAR + + @property + def recurring_price(self): + return 120 + + def delete(self, *args, **kwargs): self.network.status = 'free' self.network.save() diff --git a/uncloud_django_based/uncloud/uncloud_net/views.py b/uncloud_django_based/uncloud/uncloud_net/views.py index 1f7cf4a..dc86959 100644 --- a/uncloud_django_based/uncloud/uncloud_net/views.py +++ b/uncloud_django_based/uncloud/uncloud_net/views.py @@ -21,7 +21,8 @@ class VPNNetworkReservationViewSet(viewsets.ModelViewSet): class VPNNetworkViewSet(viewsets.ModelViewSet): serializer_class = VPNNetworkSerializer - permission_classes = [permissions.IsAdminUser] +# permission_classes = [permissions.IsAdminUser] + permission_classes = [permissions.IsAuthenticated] def get_queryset(self): if self.request.user.is_superuser: diff --git a/uncloud_django_based/uncloud/uncloud_pay/models.py b/uncloud_django_based/uncloud/uncloud_pay/models.py index aca226e..82ba3ee 100644 --- a/uncloud_django_based/uncloud/uncloud_pay/models.py +++ b/uncloud_django_based/uncloud/uncloud_pay/models.py @@ -492,6 +492,18 @@ class VATRate(models.Model): logger.debug("Did not find VAT rate for %s, returning 0" % country_code) return 0 +class BillNico(models.Model): + uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + owner = models.ForeignKey(get_user_model(), + on_delete=models.CASCADE) + + creation_date = models.DateTimeField(auto_now_add=True) + starting_date = models.DateTimeField() + ending_date = models.DateTimeField() + due_date = models.DateField() + + valid = models.BooleanField(default=True) + class Bill(models.Model): uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) owner = models.ForeignKey(get_user_model(), @@ -996,9 +1008,11 @@ class Product(UncloudModel): if not billing_address: raise ValidationError("Cannot order without a billing address") + # FIXME: allow user to choose recurring_period self.order = Order.objects.create(owner=self.owner, billing_address=billing_address, one_time_price=self.one_time_price, + recurring_period=self.default_recurring_period, recurring_price=self.recurring_price) super().save(*args, **kwargs) @@ -1019,10 +1033,6 @@ class Product(UncloudModel): def one_time_price(self): return 0 - @property - def recurring_period(self): - return self.order.recurring_period - @property def billing_address(self): return self.order.billing_address