Move vm/{detail,list} under opennebula/vm/{detail,list} and make it admin accessible only + Created vm/list that list currently authenticated user's VMs

This commit is contained in:
ahmadbilalkhalid 2020-02-22 15:49:00 +05:00
parent 5f28e9630c
commit 71a764ce1e
13 changed files with 190 additions and 28 deletions

View file

@ -1 +1,3 @@
db.sqlite3 db.sqlite3
uncloud/secrets.py
debug.log

View file

@ -31,7 +31,7 @@ class Command(BaseCommand):
user = get_user_model().objects.get(username=vm_owner) user = get_user_model().objects.get(username=vm_owner)
except get_user_model().DoesNotExist: except get_user_model().DoesNotExist:
user = get_user_model().objects.create_user(username=vm_owner) user = get_user_model().objects.create_user(username=vm_owner)
vm = json.dumps(vm, ensure_ascii=True)
vm_object = VMModel.objects.create(vmid=vm_id, owner=user, data=vm) vm_object = VMModel.objects.create(vmid=vm_id, owner=user, data=vm)
vm_object.save() vm_object.save()
else: else:

View file

@ -0,0 +1,23 @@
# Generated by Django 3.0.3 on 2020-02-22 07:13
from django.db import migrations, models
import uuid
class Migration(migrations.Migration):
dependencies = [
('opennebula', '0003_auto_20200221_1113'),
]
operations = [
migrations.RemoveField(
model_name='vm',
name='id',
),
migrations.AddField(
model_name='vm',
name='uuid',
field=models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False),
),
]

View file

@ -1,8 +1,11 @@
import uuid
from django.db import models from django.db import models
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
class VM(models.Model): class VM(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
vmid = models.IntegerField() vmid = models.IntegerField()
owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
data = models.CharField(max_length=65536, null=True) data = models.CharField(max_length=65536, null=True)

View file

@ -5,4 +5,4 @@ from opennebula.models import VM
class VMSerializer(serializers.HyperlinkedModelSerializer): class VMSerializer(serializers.HyperlinkedModelSerializer):
class Meta: class Meta:
model = VM model = VM
fields = ['vmid', 'owner', 'data'] fields = ['uuid', 'vmid', 'owner', 'data']

View file

@ -1,14 +1,59 @@
from rest_framework import viewsets, generics import json
from rest_framework import generics
from rest_framework.authentication import SessionAuthentication, BasicAuthentication
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from .models import VM from .models import VM
from .serializers import VMSerializer from .serializers import VMSerializer
class VMList(generics.ListAPIView): class VMList(generics.ListAPIView):
authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsAuthenticated, IsAdminUser]
queryset = VM.objects.all() queryset = VM.objects.all()
serializer_class = VMSerializer serializer_class = VMSerializer
class VMDetail(generics.RetrieveAPIView): class VMDetail(generics.RetrieveAPIView):
lookup_field = 'vmid' authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsAuthenticated, IsAdminUser]
lookup_field = 'uuid'
queryset = VM.objects.all() queryset = VM.objects.all()
serializer_class = VMSerializer serializer_class = VMSerializer
class UserVMList(generics.ListAPIView):
authentication_classes = [SessionAuthentication, BasicAuthentication]
permission_classes = [IsAuthenticated]
serializer_class = VMSerializer
def get_queryset(self):
user_email = self.request.user.ldap_user.attrs.data['mail']
vms = []
for mail in user_email:
vms += VM.objects.filter(owner__username=mail)
for vm in vms:
data = json.loads(vm.data)
vm_template = data['TEMPLATE']
vm.data = {
'cpu': vm_template['VCPU'],
'ram': vm_template['MEMORY'],
'nic': vm_template['NIC'],
'disks': vm_template['DISK']
}
return vms
#######################################
# Following for quick experimentation #
#######################################
# from django.http import HttpResponse
#
# def test(request):
# user_email = request.user.ldap_user.attrs.data['mail']
# vms = []
# for mail in user_email:
# vms += VM.objects.filter(owner__username=mail)
# return HttpResponse("Hello World")

View file

@ -6,3 +6,7 @@ OPENNEBULA_URL = 'https://opennebula.ungleich.ch:2634/RPC2'
# user:pass for accessing opennebula # user:pass for accessing opennebula
OPENNEBULA_USER_PASS = 'user:password' OPENNEBULA_USER_PASS = 'user:password'
AUTH_LDAP_BIND_DN = 'something'
AUTH_LDAP_BIND_PASSWORD = r'somepass'

View file

@ -12,6 +12,15 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
import os import os
import stripe
import ldap
import uncloud.secrets as secrets
from django_auth_ldap.config import LDAPSearch
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@ -106,14 +115,14 @@ AUTH_PASSWORD_VALIDATORS = [
################################################################################ ################################################################################
# AUTH/LDAP # AUTH/LDAP
import ldap
from django_auth_ldap.config import LDAPSearch, LDAPSearchUnion
AUTH_LDAP_SERVER_URI = "ldaps://ldap1.ungleich.ch,ldaps://ldap2.ungleich.ch" AUTH_LDAP_SERVER_URI = "ldaps://ldap1.ungleich.ch,ldaps://ldap2.ungleich.ch"
AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=customer,dc=ungleich,dc=ch" AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=customer,dc=ungleich,dc=ch"
AUTH_LDAP_BIND_DN = secrets.AUTH_LDAP_BIND_DN
AUTH_LDAP_BIND_PASSWORD = secrets.AUTH_LDAP_BIND_PASSWORD
AUTH_LDAP_USER_SEARCH = LDAPSearch( AUTH_LDAP_USER_SEARCH = LDAPSearch(
"ou=customer,dc=ungleich,dc=ch", ldap.SCOPE_SUBTREE, "(uid=%(user)s)" "ou=customer,dc=ungleich,dc=ch", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"
) )
@ -132,7 +141,6 @@ AUTH_USER_MODEL = 'uncloud_auth.User'
# AUTH/REST # AUTH/REST
REST_FRAMEWORK = { REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [ 'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.SessionAuthentication',
] ]
} }
@ -158,9 +166,28 @@ USE_TZ = True
STATIC_URL = '/static/' STATIC_URL = '/static/'
stripe.api_key = secrets.STRIPE_KEY
# Uncommitted file LOGGING = {
# import uncloud.secrets 'version': 1,
# 'disable_existing_loggers': False,
# import stripe 'handlers': {
# stripe.api_key = uncloud.secrets.STRIPE_KEY 'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': 'debug.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True,
},
'django_auth_ldap': {
'handlers': ['file'],
'level': 'DEBUG',
'propagate': True
}
},
}

View file

@ -32,7 +32,7 @@ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('products/', views.ProductsView.as_view(), name='products'), path('products/', views.ProductsView.as_view(), name='products'),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
path('vm/list/', oneviews.VMList.as_view(), name='vm_list'), path('opennebula/vm/list/', oneviews.VMList.as_view(), name='vm_list'),
path('vm/detail/<int:vmid>/', oneviews.VMDetail.as_view(), name='vm_detail'), path('opennebula/vm/detail/<int:vmid>/', oneviews.VMDetail.as_view(), name='vm_detail'),
path('vm/list/', oneviews.UserVMList.as_view(), name='user_vm_list'),
] ]

View file

@ -0,0 +1,46 @@
# Generated by Django 3.0.3 on 2020-02-22 07:19
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('uncloud_api', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='VMSnapshotOrder',
fields=[
('order_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='uncloud_api.Order')),
],
bases=('uncloud_api.order',),
),
migrations.CreateModel(
name='VMSnapshotProduct',
fields=[
('product_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='uncloud_api.Product')),
('gb_ssd', models.FloatField()),
('gb_hdd', models.FloatField()),
],
bases=('uncloud_api.product',),
),
migrations.DeleteModel(
name='OrderReference',
),
migrations.RemoveField(
model_name='product',
name='name',
),
migrations.RemoveField(
model_name='product',
name='recurring_period',
),
migrations.AddField(
model_name='product',
name='status',
field=models.CharField(choices=[('pending', 'Pending'), ('being_created', 'Being created'), ('created_active', 'Created'), ('deleted', 'Deleted')], default='pending', max_length=256),
),
]

View file

@ -31,18 +31,21 @@ from django.contrib.auth import get_user_model
# logs # logs
# Should have a log = ... => 1:n field for most models! # Should have a log = ... => 1:n field for most models!
class Product(models.Model): class Product(models.Model):
# override these fields by default # override these fields by default
description = "" description = ""
recurring_period = "not_recurring" recurring_period = "not_recurring"
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
status = models.CharField(max_length=256, status = models.CharField(
choices = ( max_length=256, choices=(
('pending', 'Pending'), ('pending', 'Pending'),
('being_created', 'Being created'), ('being_created', 'Being created'),
('created_active', 'Created'), ('created_active', 'Created'),
('deleted', 'Deleted') ('deleted', 'Deleted')
) ),
default='pending'
)
def __str__(self): def __str__(self):
return "{}".format(self.name) return "{}".format(self.name)
@ -86,7 +89,6 @@ Sample price for a VM with {} GB SSD and {} GB HDD VM is: {}.
gb_hdd = models.FloatField() gb_hdd = models.FloatField()
class Feature(models.Model): class Feature(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=256) name = models.CharField(max_length=256)

11
notes-abk.md Normal file
View file

@ -0,0 +1,11 @@
## TODO 2020-02-22
* ~~move the current rest api to /opennebula~~
* ~~make the /opennebula api only accessible by an admin account~~
* ~~create a new filtered api on /vm/list that~~
* ~~a) requires authentication~~
* ~~b) only shows the VMs of the current user~~
* ~~the new api should not contain all details, but: cpus (as read by the vcpu field), ram, ips, disks~~
* ~~also make a (random) uuid the primary key for VMs - everything in this uncloud hack will use uuids as the id~~
* ~~still expose the opennebula id as opennebula_id~~
* ~~note put all secrets/configs into uncloud.secrets - I added a sample file into the repo~~

View file

@ -1 +0,0 @@
*