279 lines
9.2 KiB
Python
279 lines
9.2 KiB
Python
|
||
from django.shortcuts import render
|
||
from rest_framework.response import Response
|
||
from rest_framework.views import APIView
|
||
from rest_framework.permissions import IsAuthenticated
|
||
from django.conf import settings
|
||
import os
|
||
from apps.ops.serializers import DbbackupDeleteSerializer, MemDiskSerializer, CpuSerializer, DrfRequestLogSerializer, TlogSerializer, TextListSerializer
|
||
from rest_framework.exceptions import NotFound
|
||
from rest_framework.mixins import ListModelMixin
|
||
from apps.ops.filters import DrfLogFilterSet, TlogFilterSet
|
||
from apps.ops.models import DrfRequestLog, Tlog
|
||
|
||
from apps.ops.errors import LOG_NOT_FONED
|
||
from apps.utils.viewsets import CustomGenericViewSet
|
||
from rest_framework.exceptions import APIException
|
||
from apps.ops.tasks import reload_server_git, reload_server_only, reload_web_git, backup_database, backup_media
|
||
from rest_framework.permissions import IsAdminUser
|
||
from drf_yasg.utils import swagger_auto_schema
|
||
from apps.ops.service import ServerService, CeleryMonitor, RedisMonitor
|
||
from server.settings import BACKUP_PATH
|
||
# Create your views here.
|
||
|
||
|
||
def index(request):
|
||
return render(request, 'ops/index.html')
|
||
|
||
|
||
def room(request, room_name):
|
||
return render(request, 'ops/room.html', {
|
||
'room_name': room_name
|
||
})
|
||
|
||
|
||
class ReloadServerGit(APIView):
|
||
permission_classes = [IsAdminUser]
|
||
|
||
@swagger_auto_schema(operation_summary="拉取后端代码并重启服务", responses=None, request_body=None)
|
||
def post(self, request):
|
||
reload_server_git.delay()
|
||
return Response()
|
||
# if completed.returncode == 0:
|
||
# return Response()
|
||
# else:
|
||
# from server.settings import myLogger
|
||
# myLogger.error(completed)
|
||
# raise ParseError(completed.stderr)
|
||
|
||
|
||
class ReloadClientGit(APIView):
|
||
permission_classes = [IsAdminUser]
|
||
|
||
@swagger_auto_schema(operation_summary="拉取前端代码并打包", responses=None, request_body=None)
|
||
def post(self, request):
|
||
reload_web_git.delay()
|
||
return Response()
|
||
# completed = reload_web_git()
|
||
# if completed.returncode == 0:
|
||
# return Response()
|
||
# else:
|
||
# raise APIException(completed.stdout)
|
||
|
||
|
||
class ReloadServerOnly(APIView):
|
||
permission_classes = [IsAdminUser]
|
||
|
||
@swagger_auto_schema(operation_summary="仅重启服务", responses=None, request_body=None)
|
||
def post(self, request):
|
||
completed = reload_server_only()
|
||
if completed.returncode == 0:
|
||
return Response()
|
||
else:
|
||
raise APIException(completed.stdout)
|
||
|
||
|
||
class BackupDatabase(APIView):
|
||
permission_classes = [IsAdminUser]
|
||
|
||
@swagger_auto_schema(operation_summary="备份数据库到指定位置", responses=None, request_body=None)
|
||
def post(self, request):
|
||
err_str = backup_database()
|
||
if err_str:
|
||
raise APIException(err_str)
|
||
return Response()
|
||
|
||
|
||
class BackupMedia(APIView):
|
||
permission_classes = [IsAdminUser]
|
||
|
||
@swagger_auto_schema(operation_summary="备份资源到指定位置", responses=None, request_body=None)
|
||
def post(self, request):
|
||
err_str = backup_media()
|
||
if err_str:
|
||
raise APIException(err_str)
|
||
return Response()
|
||
|
||
|
||
class CpuView(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
@swagger_auto_schema(operation_summary="获取服务器cpu当前状态", responses={200: CpuSerializer}, request_body=None)
|
||
def get(self, request, *args, **kwargs):
|
||
return Response(ServerService.get_cpu_dict())
|
||
|
||
|
||
class MemoryView(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
@swagger_auto_schema(operation_summary="获取服务器内存当前状态", responses={200: MemDiskSerializer}, request_body=None)
|
||
def get(self, request, *args, **kwargs):
|
||
return Response(ServerService.get_memory_dict())
|
||
|
||
|
||
class DiskView(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
@swagger_auto_schema(operation_summary="获取服务器硬盘当前状态", responses={200: MemDiskSerializer}, request_body=None)
|
||
def get(self, request, *args, **kwargs):
|
||
return Response(ServerService.get_disk_dict())
|
||
|
||
|
||
def get_file_list(file_path):
|
||
dir_list = os.listdir(file_path)
|
||
if not dir_list:
|
||
return
|
||
else:
|
||
# 注意,这里使用lambda表达式,将文件按照最后修改时间顺序升序排列
|
||
# os.path.getmtime() 函数是获取文件最后修改时间
|
||
# os.path.getctime() 函数是获取文件最后创建时间
|
||
dir_list = sorted(dir_list, key=lambda x: os.path.getmtime(
|
||
os.path.join(file_path, x)), reverse=True)
|
||
# print(dir_list)
|
||
return dir_list
|
||
|
||
|
||
class LogView(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
@swagger_auto_schema(operation_summary="查看最近的日志列表", responses={200: TextListSerializer(many=True)}, request_body=None)
|
||
def get(self, request, *args, **kwargs):
|
||
logs = []
|
||
name = request.GET.get('name', None)
|
||
# for root, dirs, files in os.walk(settings.LOG_PATH):
|
||
# files.reverse()
|
||
for file in get_file_list(settings.LOG_PATH):
|
||
if len(logs) > 50:
|
||
break
|
||
filepath = os.path.join(settings.LOG_PATH, file)
|
||
if name:
|
||
if name in filepath:
|
||
fsize = os.path.getsize(filepath)
|
||
if fsize:
|
||
logs.append({
|
||
"name": file,
|
||
"filepath": filepath,
|
||
"size": round(fsize/1024, 1)
|
||
})
|
||
else:
|
||
fsize = os.path.getsize(filepath)
|
||
if fsize:
|
||
logs.append({
|
||
"name": file,
|
||
"filepath": filepath,
|
||
"size": round(fsize/1024, 1)
|
||
})
|
||
return Response(logs)
|
||
|
||
|
||
class LogDetailView(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
@swagger_auto_schema(operation_summary="查看日志详情", responses=None)
|
||
def get(self, request, name):
|
||
try:
|
||
with open(os.path.join(settings.LOG_PATH, name)) as f:
|
||
data = f.read()
|
||
return Response(data)
|
||
except Exception:
|
||
raise NotFound(**LOG_NOT_FONED)
|
||
|
||
|
||
class DbBackupDeleteView(APIView):
|
||
perms_map = {'delete': 'dbback.delete'}
|
||
|
||
@swagger_auto_schema(operation_summary="删除备份", responses={204: None})
|
||
def delete(self, request, filepath):
|
||
if BACKUP_PATH in filepath:
|
||
os.remove(filepath)
|
||
return Response()
|
||
|
||
|
||
class DbBackupView(APIView):
|
||
perms_map = {'get': '*', 'post': 'dbback.delete'}
|
||
|
||
@swagger_auto_schema(operation_summary="批量删除备份", responses={204: None}, request_body=DbbackupDeleteSerializer)
|
||
def post(self, request):
|
||
filepaths = request.data.get('filepaths', [])
|
||
for i in filepaths:
|
||
if BACKUP_PATH in i:
|
||
os.remove(i)
|
||
return Response()
|
||
|
||
@swagger_auto_schema(operation_summary="查看最近的备份列表", responses={200: TextListSerializer(many=True)}, request_body=None)
|
||
def get(self, request, *args, **kwargs):
|
||
items = []
|
||
name = request.GET.get('name', None)
|
||
backpath = settings.BACKUP_PATH + '/database'
|
||
for file in get_file_list(backpath):
|
||
if len(items) > 50:
|
||
break
|
||
filepath = os.path.join(backpath, file)
|
||
if name:
|
||
if name in filepath:
|
||
fsize = os.path.getsize(filepath)
|
||
if fsize:
|
||
items.append({
|
||
"name": file,
|
||
"filepath": filepath,
|
||
"size": round(fsize/1024/1024, 1)
|
||
})
|
||
else:
|
||
fsize = os.path.getsize(filepath)
|
||
if fsize:
|
||
items.append({
|
||
"name": file,
|
||
"filepath": filepath,
|
||
"size": round(fsize/1024/1024, 1)
|
||
})
|
||
return Response(items)
|
||
|
||
|
||
class DrfRequestLogViewSet(ListModelMixin, CustomGenericViewSet):
|
||
"""list:请求日志
|
||
|
||
请求日志
|
||
"""
|
||
perms_map = {'get': '*'}
|
||
queryset = DrfRequestLog.objects.all()
|
||
list_serializer_class = DrfRequestLogSerializer
|
||
ordering = ['-requested_at']
|
||
filterset_class = DrfLogFilterSet
|
||
search_fields = ['path', 'view']
|
||
|
||
|
||
class TlogViewSet(ListModelMixin, CustomGenericViewSet):
|
||
"""list:三方日志查看
|
||
|
||
三方日志查看
|
||
"""
|
||
perms_map = {'get': '*'}
|
||
queryset = Tlog.objects.all()
|
||
list_serializer_class = TlogSerializer
|
||
ordering = ['-requested_at']
|
||
filterset_class = TlogFilterSet
|
||
search_fields = ['path']
|
||
|
||
class CeleryInfoView(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
def get(self, request, *args, **kwargs):
|
||
"""
|
||
获取celery状态信息
|
||
|
||
获取celery状态信息
|
||
"""
|
||
return Response(CeleryMonitor.get_info())
|
||
|
||
|
||
class RedisInfoView(APIView):
|
||
permission_classes = [IsAuthenticated]
|
||
|
||
def get(self, request, *args, **kwargs):
|
||
"""
|
||
获取redis状态信息
|
||
|
||
获取redis状态信息
|
||
"""
|
||
return Response(RedisMonitor.get_info())
|