mirror of
https://github.com/retspen/webvirtcloud
synced 2025-07-31 12:41:08 +00:00
Rest framework (#24)
* Add rest framework for API: First Commit * modify some shell scripts to make variable references safer; modify some python scripts to reduce the code complexity and cyclomatic complexity of functions. * Add REST API for some webvirtcloud functions. Instance list/delete/create, compute list/delete/create, storages-network list/retrieve. Add swagger and redoc for API interface * update requirements Co-authored-by: herengui <herengui@uniontech.com>
This commit is contained in:
parent
92254401dc
commit
cfce71ec2b
42 changed files with 1170 additions and 348 deletions
|
@ -7,28 +7,20 @@ register = template.Library()
|
|||
|
||||
@register.simple_tag
|
||||
def app_active(request, app_name):
|
||||
if request.resolver_match.app_name == app_name:
|
||||
return "active"
|
||||
return ""
|
||||
return "active" if request.resolver_match.app_name == app_name else ""
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def view_active(request, view_name):
|
||||
if request.resolver_match.view_name == view_name:
|
||||
return "active"
|
||||
return ""
|
||||
return "active" if request.resolver_match.view_name == view_name else ""
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def class_active(request, pattern):
|
||||
if re.search(pattern, request.path):
|
||||
# Not sure why 'class="active"' returns class=""active""
|
||||
return "active"
|
||||
return ""
|
||||
# Not sure why 'class="active"' returns class=""active""
|
||||
return "active" if re.search(pattern, request.path) else ""
|
||||
|
||||
|
||||
@register.simple_tag
|
||||
def has_perm(user, permission_codename):
|
||||
if user.has_perm(permission_codename):
|
||||
return True
|
||||
return False
|
||||
return bool(user.has_perm(permission_codename))
|
||||
|
|
|
@ -42,48 +42,49 @@ try:
|
|||
|
||||
def authenticate(self, request, username=None, password=None, **kwargs):
|
||||
if not settings.LDAP_ENABLED:
|
||||
return None
|
||||
return None
|
||||
print("authenticate_ldap")
|
||||
# Get the user information from the LDAP if he can be authenticated
|
||||
isAdmin = False
|
||||
isStaff = False
|
||||
isTechnician = False
|
||||
|
||||
|
||||
requeteLdap = self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_ADMINS)
|
||||
isAdmin = requeteLdap is not None
|
||||
isStaff = requeteLdap is not None
|
||||
|
||||
if requeteLdap is None:
|
||||
requeteLdap = self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_STAFF)
|
||||
if requeteLdap is None:
|
||||
requeteLdap = self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_TECHNICIANS)
|
||||
if requeteLdap is None:
|
||||
requeteLdap = self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_USERS)
|
||||
if requeteLdap is None:
|
||||
print("User does not belong to any search group. Check LDAP_SEARCH_GROUP_FILTER in settings.")
|
||||
return None
|
||||
else:
|
||||
isTechnician = True
|
||||
else:
|
||||
isStaff = True
|
||||
else:
|
||||
isAdmin = True
|
||||
isStaff = True
|
||||
isStaff = requeteLdap is not None
|
||||
|
||||
if requeteLdap is None:
|
||||
requeteLdap = self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_TECHNICIANS)
|
||||
isTechnician = requeteLdap is not None
|
||||
|
||||
if requeteLdap is None:
|
||||
requeteLdap = self.get_LDAP_user(username, password, settings.LDAP_SEARCH_GROUP_FILTER_USERS)
|
||||
|
||||
if requeteLdap is None:
|
||||
print("User does not belong to any search group. Check LDAP_SEARCH_GROUP_FILTER in settings.")
|
||||
return None
|
||||
|
||||
techniciansGroup = Group.objects.get(name='Technicians')
|
||||
|
||||
|
||||
try:
|
||||
user = User.objects.get(username=username)
|
||||
attributes = UserAttributes.objects.get(user=user)
|
||||
user.is_staff = isStaff
|
||||
user.is_superuser = isAdmin
|
||||
if isTechnician is False and user.groups.filter(name='Technicians').exists():
|
||||
if not isTechnician and user.groups.filter(name='Technicians').exists():
|
||||
user.groups.remove(techniciansGroup)
|
||||
elif isTechnician is True and user.groups.filter(name='Technicians').exists() is False:
|
||||
elif isTechnician and not user.groups.filter(name='Technicians').exists():
|
||||
user.groups.add(techniciansGroup)
|
||||
else:
|
||||
print("The user is already in the Technicians group")
|
||||
user.save()
|
||||
# TODO VERIFY
|
||||
except User.DoesNotExist:
|
||||
print("authenticate-create new user: {}".format(username))
|
||||
print(f"authenticate-create new user: {username}")
|
||||
user = User(username=username)
|
||||
user.first_name = requeteLdap[1]
|
||||
user.last_name = requeteLdap[2]
|
||||
|
@ -93,7 +94,7 @@ try:
|
|||
user.is_superuser = isAdmin
|
||||
user.set_password(uuid.uuid4().hex)
|
||||
user.save()
|
||||
if isTechnician is True:
|
||||
if isTechnician:
|
||||
user.groups.add(techniciansGroup)
|
||||
maxInstances = 1
|
||||
maxCpus = 1
|
||||
|
|
|
@ -22,10 +22,12 @@ INSTALLED_APPS = [
|
|||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"rest_framework",
|
||||
"django_bootstrap5",
|
||||
"django_icons",
|
||||
"django_otp",
|
||||
"django_otp.plugins.otp_totp",
|
||||
"drf_yasg",
|
||||
"accounts",
|
||||
"admin",
|
||||
"appsettings",
|
||||
|
@ -40,6 +42,7 @@ INSTALLED_APPS = [
|
|||
"virtsecrets",
|
||||
"logs",
|
||||
"qr_code",
|
||||
"rest_framework",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -211,7 +214,7 @@ SOCKETIO_PUBLIC_PORT = 6081
|
|||
SOCKETIO_PUBLIC_PATH = "socket.io/"
|
||||
|
||||
# List of console listen addresses
|
||||
QEMU_CONSOLE_LISTEN_ADDRESSES = (
|
||||
QEMU_CONSOLE_LISTENER_ADDRESSES = (
|
||||
("127.0.0.1", "Localhost"),
|
||||
("0.0.0.0", "All interfaces"),
|
||||
)
|
||||
|
|
37
webvirtcloud/urls-api.py
Normal file
37
webvirtcloud/urls-api.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
from django.urls import include, path
|
||||
from rest_framework_nested import routers
|
||||
|
||||
from computes.api.viewsets import ComputeArchitecturesView, ComputeViewSet
|
||||
from networks.api.viewsets import NetworkViewSet
|
||||
from interfaces.api.viewsets import InterfaceViewSet
|
||||
from storages.api.viewsets import StorageViewSet, VolumeViewSet
|
||||
from instances.api.viewsets import FlavorViewSet, \
|
||||
InstancesViewSet, \
|
||||
InstanceViewSet, \
|
||||
MigrateViewSet, \
|
||||
CreateInstanceViewSet
|
||||
|
||||
|
||||
router = routers.SimpleRouter()
|
||||
router.register(r'computes', ComputeViewSet)
|
||||
router.register(r'migrate', MigrateViewSet, basename='instance-migrate')
|
||||
router.register(r'flavor', FlavorViewSet, basename='instance-flavor')
|
||||
router.register(r'instances', InstancesViewSet, basename='instance')
|
||||
|
||||
compute_router = routers.NestedSimpleRouter(router, r'computes', lookup='compute')
|
||||
compute_router.register(r'instances', InstanceViewSet, basename='compute-instance')
|
||||
compute_router.register(r'instances/create/(?P<arch>[^/.]+)/(?P<machine>[^/.]+)', CreateInstanceViewSet, basename='instance-create')
|
||||
compute_router.register(r'networks', NetworkViewSet, basename='compute-network')
|
||||
compute_router.register(r'interfaces', InterfaceViewSet, basename='compute-interface')
|
||||
compute_router.register(r'storages', StorageViewSet, basename='compute-storage')
|
||||
compute_router.register(r'archs', ComputeArchitecturesView, basename='compute-archs')
|
||||
|
||||
storage_router = routers.NestedSimpleRouter(compute_router, r'storages', lookup='storage')
|
||||
storage_router.register(r'volumes', VolumeViewSet, basename='compute-storage-volumes')
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path('', include(router.urls)),
|
||||
path('', include(compute_router.urls)),
|
||||
path('', include(storage_router.urls)),
|
||||
]
|
|
@ -1,9 +1,26 @@
|
|||
from django.conf import settings
|
||||
from django.urls import include, path, re_path
|
||||
from rest_framework import permissions
|
||||
from drf_yasg.views import get_schema_view
|
||||
from drf_yasg import openapi
|
||||
from appsettings.views import appsettings
|
||||
from console.views import console
|
||||
from django.conf import settings
|
||||
from django.urls import include, path
|
||||
from instances.views import index
|
||||
|
||||
|
||||
schema_view = get_schema_view(
|
||||
openapi.Info(
|
||||
title="Webvirtcloud REST-API",
|
||||
default_version='v1',
|
||||
description="Webvirtcloud REST API",
|
||||
terms_of_service="https://www.google.com/policies/terms/",
|
||||
contact=openapi.Contact(email="catborise@gmail.com"),
|
||||
license=openapi.License(name="BSD License"),
|
||||
),
|
||||
public=True,
|
||||
permission_classes=(permissions.AllowAny,),
|
||||
)
|
||||
|
||||
urlpatterns = [
|
||||
path("", index, name="index"),
|
||||
path("admin/", include(("admin.urls", "admin"), namespace="admin")),
|
||||
|
@ -15,6 +32,11 @@ urlpatterns = [
|
|||
path("instances/", include("instances.urls")),
|
||||
path("i18n/", include("django.conf.urls.i18n")),
|
||||
path("logs/", include("logs.urls")),
|
||||
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
|
||||
path('api/v1/', include("webvirtcloud.urls-api")),
|
||||
re_path(r'^swagger(?P<format>\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
|
||||
re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
|
||||
re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
|
||||
]
|
||||
|
||||
if settings.DEBUG:
|
||||
|
@ -26,3 +48,4 @@ if settings.DEBUG:
|
|||
]
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue