In between commit
This commit is contained in:
parent
99a18232aa
commit
41a2f18453
4 changed files with 71 additions and 13 deletions
|
@ -57,18 +57,11 @@ After postresql is started, apply the migrations:
|
||||||
python manage.py migrate
|
python manage.py migrate
|
||||||
```
|
```
|
||||||
|
|
||||||
### Secrets
|
|
||||||
|
|
||||||
cp `uncloud/secrets_sample.py` to `uncloud/secrets.py` and replace the
|
|
||||||
sample values with real values.
|
|
||||||
|
|
||||||
|
|
||||||
## Flows / Orders
|
## Flows / Orders
|
||||||
|
|
||||||
|
|
||||||
### Creating a VMHost
|
### Creating a VMHost
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Creating a VM
|
### Creating a VM
|
||||||
|
|
||||||
* Create a VMHost
|
* 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)
|
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/<uuid> should list uuids of disks
|
||||||
|
* UPDATE on ../vm/disk/<uuid> with size=newsize
|
||||||
|
* Newsize > oldsize!
|
||||||
|
* Triggers shutdown of VM
|
||||||
|
* Resizes disk
|
||||||
|
* Starts VM
|
||||||
|
* Maybe confirm flag?
|
||||||
|
|
||||||
|
|
||||||
|
### Adding a disk to a VM
|
||||||
|
|
||||||
|
(TBD)
|
||||||
|
|
|
@ -173,6 +173,13 @@ class VPNNetwork(Product):
|
||||||
|
|
||||||
wireguard_public_key = models.CharField(max_length=48)
|
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):
|
def delete(self, *args, **kwargs):
|
||||||
self.network.status = 'free'
|
self.network.status = 'free'
|
||||||
self.network.save()
|
self.network.save()
|
||||||
|
|
|
@ -21,7 +21,8 @@ class VPNNetworkReservationViewSet(viewsets.ModelViewSet):
|
||||||
|
|
||||||
class VPNNetworkViewSet(viewsets.ModelViewSet):
|
class VPNNetworkViewSet(viewsets.ModelViewSet):
|
||||||
serializer_class = VPNNetworkSerializer
|
serializer_class = VPNNetworkSerializer
|
||||||
permission_classes = [permissions.IsAdminUser]
|
# permission_classes = [permissions.IsAdminUser]
|
||||||
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
if self.request.user.is_superuser:
|
if self.request.user.is_superuser:
|
||||||
|
|
|
@ -492,6 +492,18 @@ class VATRate(models.Model):
|
||||||
logger.debug("Did not find VAT rate for %s, returning 0" % country_code)
|
logger.debug("Did not find VAT rate for %s, returning 0" % country_code)
|
||||||
return 0
|
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):
|
class Bill(models.Model):
|
||||||
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||||
owner = models.ForeignKey(get_user_model(),
|
owner = models.ForeignKey(get_user_model(),
|
||||||
|
@ -996,9 +1008,11 @@ class Product(UncloudModel):
|
||||||
if not billing_address:
|
if not billing_address:
|
||||||
raise ValidationError("Cannot order without a 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,
|
self.order = Order.objects.create(owner=self.owner,
|
||||||
billing_address=billing_address,
|
billing_address=billing_address,
|
||||||
one_time_price=self.one_time_price,
|
one_time_price=self.one_time_price,
|
||||||
|
recurring_period=self.default_recurring_period,
|
||||||
recurring_price=self.recurring_price)
|
recurring_price=self.recurring_price)
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
@ -1019,10 +1033,6 @@ class Product(UncloudModel):
|
||||||
def one_time_price(self):
|
def one_time_price(self):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
@property
|
|
||||||
def recurring_period(self):
|
|
||||||
return self.order.recurring_period
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def billing_address(self):
|
def billing_address(self):
|
||||||
return self.order.billing_address
|
return self.order.billing_address
|
||||||
|
|
Loading…
Reference in a new issue