factory/apps/ops/views.py

279 lines
9.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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())