diff --git a/apps/celerybeat-schedule.db b/apps/celerybeat-schedule.db deleted file mode 100644 index e69de29bb..000000000 diff --git a/apps/celerybeat.pid b/apps/celerybeat.pid deleted file mode 100644 index a5a55e28c..000000000 --- a/apps/celerybeat.pid +++ /dev/null @@ -1 +0,0 @@ -64256 diff --git a/apps/common/__init__.py b/apps/common/__init__.py index 02bbfb61f..b64e43e83 100644 --- a/apps/common/__init__.py +++ b/apps/common/__init__.py @@ -2,5 +2,4 @@ from __future__ import absolute_import # This will make sure the app is always imported when # Django starts so that shared_task will use this app. -# from .celery import app as celery_app - +from .celery import app as celery_app diff --git a/apps/common/celery.py b/apps/common/celery.py index 681ce6a6a..f4ea048e5 100644 --- a/apps/common/celery.py +++ b/apps/common/celery.py @@ -1,20 +1,20 @@ -# # ~*~ coding: utf-8 ~*~ -# -# from __future__ import absolute_import, unicode_literals -# import os -# -# from celery import Celery -# -# # set the default Django settings module for the 'celery' program. -# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'jumpserver.settings') -# -# from django.conf import settings -# -# app = Celery('jumpserver') -# -# # Using a string here means the worker will not have to -# # pickle the object when using Windows. -# app.config_from_object('django.conf:settings') -# -# app.autodiscover_tasks(lambda: [app_config.split('.')[0] for app_config in settings.INSTALLED_APPS]) -# +# ~*~ coding: utf-8 ~*~ + +from __future__ import absolute_import, unicode_literals +import os +from datetime import timedelta + +from celery import Celery + +# set the default Django settings module for the 'celery' program. +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'jumpserver.settings') + +from django.conf import settings + +app = Celery('jumpserver') + +# Using a string here means the worker will not have to +# pickle the object when using Windows. +app.config_from_object('django.conf:settings') +app.autodiscover_tasks(lambda: [app_config.split('.')[0] for app_config in settings.INSTALLED_APPS]) + diff --git a/apps/common/tasks.py b/apps/common/tasks.py index 43d35f313..11d0d711d 100644 --- a/apps/common/tasks.py +++ b/apps/common/tasks.py @@ -1,26 +1,9 @@ from __future__ import absolute_import -import os -from celery import shared_task -from celery.schedules import crontab +# from celery import shared_task from django.core.mail import send_mail -# from django.conf import settings -# from common import celery_app - - -from celery import Celery - -# set the default Django settings module for the 'celery' program. -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'jumpserver.settings') - from django.conf import settings - -app = Celery('jumpserver') - -# Using a string here means the worker will not have to -# pickle the object when using Windows. -app.config_from_object('django.conf:settings') -app.autodiscover_tasks(lambda: [app_config.split('.')[0] for app_config in settings.INSTALLED_APPS]) +from common import celery_app as app @app.task @@ -44,17 +27,3 @@ def send_mail_async(*args, **kwargs): args = tuple(args) send_mail(*args, **kwargs) - - -# @celery_app.task -# def test(arg): -# print(arg) - - -# celery_app.conf.beat_schedule = { -# 'add-every-30-seconds': { -# 'task': 'common.test', -# 'schedule': crontab(minute='*/1'), -# 'args': ('nihao',) -# } -# } diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index e06158852..3f31995d6 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -14,6 +14,7 @@ import os import sys from django.urls import reverse_lazy +from datetime import timedelta # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) @@ -284,6 +285,19 @@ BROKER_URL = 'redis://%(password)s%(host)s:%(port)s/3' % { } CELERY_RESULT_BACKEND = BROKER_URL +# TERMINAL_HEATBEAT_INTERVAL = CONFIG.TERMINAL_HEATBEAT_INTERVAL or 30 + +# crontab job +# CELERYBEAT_SCHEDULE = { +# Check terminal is alive every 10m + # 'check_terminal_alive': { + # 'task': 'terminal.tasks.check_terminal_alive', + # 'schedule': timedelta(seconds=TERMINAL_HEATBEAT_INTERVAL), + # 'args': (), + # }, +# } + + # Cache use redis CACHES = { 'default': { diff --git a/apps/terminal/api.py b/apps/terminal/api.py index a895723d4..224dac98b 100644 --- a/apps/terminal/api.py +++ b/apps/terminal/api.py @@ -4,17 +4,17 @@ from django.core.cache import cache from django.conf import settings from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView +from rest_framework import viewsets from rest_framework.views import APIView, Response -from rest_framework.viewsets import ModelViewSet from rest_framework.permissions import AllowAny from common.utils import signer, get_object_or_none -from .models import Terminal, HeatbeatFailedLog +from .models import Terminal, TerminalHeatbeat from .serializers import TerminalSerializer, TerminalHeatbeatSerializer from .hands import IsSuperUserOrTerminalUser -class TerminalViewSet(ModelViewSet): +class TerminalViewSet(viewsets.ModelViewSet): queryset = Terminal.objects.all() serializer_class = TerminalSerializer permission_classes = (AllowAny,) @@ -46,18 +46,19 @@ class TerminalViewSet(ModelViewSet): return Response(data={'msg': 'Secrete key invalid'}, status=401) -class TerminalHeatbeatApi(APIView): - # model = HeatbeatFailedLog - # serializer_class = TerminalHeatbeatSerializer +class TerminalHeatbeatApi(ListCreateAPIView): + queryset = TerminalHeatbeat.objects.all() + serializer_class = TerminalHeatbeatSerializer permission_classes = (IsSuperUserOrTerminalUser,) - def put(self, request, *args, **kwargs): - terminal_id = request.user.id - cache.set('terminal_heatbeat_%s' % terminal_id, settings.CONFIG.TERMINAL_HEATBEAT_INTERVAL * 3) + +class TerminalHeatbeatViewSet(viewsets.ModelViewSet): + queryset = TerminalHeatbeat.objects.all() + serializer_class = TerminalHeatbeatSerializer + permission_classes = (IsSuperUserOrTerminalUser,) + + def create(self, request, *args, **kwargs): + terminal = request.user + TerminalHeatbeat.objects.create(terminal=terminal) return Response({'msg': 'Success'}) - -# class TerminalApiDetailUpdateDetailApi(RetrieveUpdateDestroyAPIView): -# queryset = Terminal.objects.all() -# serializer_class = TerminalSerializer -# permission_classes = (IsSuperUserOrTerminalUser,) diff --git a/apps/terminal/models.py b/apps/terminal/models.py index e64a43d89..8b65ed6da 100644 --- a/apps/terminal/models.py +++ b/apps/terminal/models.py @@ -36,10 +36,9 @@ class Terminal(models.Model): ordering = ['is_active'] -class HeatbeatFailedLog(models.Model): - """Terminal heatbeat failed log""" +class TerminalHeatbeat(models.Model): terminal = models.ForeignKey(Terminal, on_delete=models.CASCADE) date_created = models.DateTimeField(auto_now_add=True) class Meta: - db_table = 'heatbeat_failed_log' + db_table = 'terminal_heatbeat' diff --git a/apps/terminal/serializers.py b/apps/terminal/serializers.py index d025f7254..2903fa896 100644 --- a/apps/terminal/serializers.py +++ b/apps/terminal/serializers.py @@ -1,29 +1,38 @@ # -*- coding: utf-8 -*- # +from django.utils import timezone from rest_framework import serializers -from .models import Terminal, HeatbeatFailedLog +from .models import Terminal, TerminalHeatbeat from .hands import ProxyLog class TerminalSerializer(serializers.ModelSerializer): proxy_online = serializers.SerializerMethodField() + is_alive = serializers.SerializerMethodField() class Meta: model = Terminal fields = ['id', 'name', 'ip', 'type', 'url', 'comment', - 'is_active', 'get_type_display', 'proxy_online'] + 'is_active', 'get_type_display', 'proxy_online', 'is_alive'] @staticmethod def get_proxy_online(obj): return ProxyLog.objects.filter(terminal=obj.name, is_finished=False).count() + @staticmethod + def get_is_alive(obj): + log = obj.terminalheatbeat_set.last() + if timezone.now() - log.date_created > timezone.timedelta(seconds=600): + return False + else: + return True + class TerminalHeatbeatSerializer(serializers.ModelSerializer): class Meta: - model = HeatbeatFailedLog - fields = ['terminal'] + model = TerminalHeatbeat if __name__ == '__main__': diff --git a/apps/terminal/tasks.py b/apps/terminal/tasks.py new file mode 100644 index 000000000..69a80f243 --- /dev/null +++ b/apps/terminal/tasks.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# + + diff --git a/apps/terminal/urls.py b/apps/terminal/urls.py index 215e9f3cb..03bc6ce9e 100644 --- a/apps/terminal/urls.py +++ b/apps/terminal/urls.py @@ -16,10 +16,10 @@ urlpatterns = [ ] router = routers.DefaultRouter() +router.register(r'v1/terminal/heatbeat', api.TerminalHeatbeatViewSet, 'api-terminal-heatbeat') router.register(r'v1/terminal', api.TerminalViewSet, 'api-terminal') - -urlpatterns += [ - url(r'^v1/terminal/heatbeat/$', api.TerminalHeatbeatApi.as_view(), name='terminal-heatbeat-api'), -] +# urlpatterns += [ +# url(r'v1/terminal/heatbeat/', api.TerminalHeatbeatApi.as_view(), name='api-terminal-heatbeat') +# ] urlpatterns += router.urls diff --git a/run_server.py b/run_server.py index 689740f0f..3d69eb5f0 100644 --- a/run_server.py +++ b/run_server.py @@ -30,7 +30,7 @@ def start_celery(): os.chdir(apps_dir) os.environ.setdefault('C_FORCE_ROOT', '1') print('start celery') - subprocess.call('celery -A common worker -l info', shell=True) + subprocess.call('celery -A common worker -B -s /tmp/celerybeat-schedule -l info ', shell=True) def main():