提交 bf9bb1b9 编写于 作者: baltery's avatar baltery

[Update] 修改ops task运行

上级 30efec1b
......@@ -25,9 +25,9 @@ from .hands import IsSuperUser, IsValidUser, IsSuperUserOrAppUser, \
get_user_granted_assets
from .models import AssetGroup, Asset, Cluster, SystemUser, AdminUser
from . import serializers
from .tasks import update_assets_hardware_info, test_admin_user_connectability, \
test_admin_user_connectability_manual, push_system_user_to_cluster_assets, \
test_system_user_connectability
from .tasks import update_assets_hardware_info_manual, test_admin_user_connectability_util, \
test_asset_connectability_manual, push_system_user_to_cluster_assets_manual, \
test_system_user_connectability_manual
class AssetViewSet(IDInFilterMixin, BulkModelViewSet):
......@@ -222,7 +222,7 @@ class AssetRefreshHardwareApi(generics.RetrieveAPIView):
def retrieve(self, request, *args, **kwargs):
asset_id = kwargs.get('pk')
asset = get_object_or_404(Asset, pk=asset_id)
summary = update_assets_hardware_info([asset])
summary = update_assets_hardware_info_manual([asset])
if summary.get('dark'):
return Response(summary['dark'].values(), status=501)
else:
......@@ -239,7 +239,7 @@ class AssetAdminUserTestApi(generics.RetrieveAPIView):
def retrieve(self, request, *args, **kwargs):
asset_id = kwargs.get('pk')
asset = get_object_or_404(Asset, pk=asset_id)
ok, msg = test_admin_user_connectability_manual(asset)
ok, msg = test_asset_connectability_manual(asset)
if ok:
return Response({"msg": "pong"})
else:
......@@ -255,7 +255,7 @@ class AdminUserTestConnectiveApi(generics.RetrieveAPIView):
def retrieve(self, request, *args, **kwargs):
admin_user = self.get_object()
test_admin_user_connectability.delay(admin_user, force=True)
test_admin_user_connectability_util.delay(admin_user, force=True)
return Response({"msg": "Task created"})
......@@ -268,7 +268,7 @@ class SystemUserPushApi(generics.RetrieveAPIView):
def retrieve(self, request, *args, **kwargs):
system_user = self.get_object()
push_system_user_to_cluster_assets.delay(system_user, force=True)
push_system_user_to_cluster_assets_manual.delay(system_user, force=True)
return Response({"msg": "Task created"})
......@@ -281,5 +281,5 @@ class SystemUserTestConnectiveApi(generics.RetrieveAPIView):
def retrieve(self, request, *args, **kwargs):
system_user = self.get_object()
test_system_user_connectability.delay(system_user, force=True)
test_system_user_connectability_manual.delay(system_user, force=True)
return Response({"msg": "Task created"})
......@@ -2,14 +2,20 @@
#
from django.utils.translation import ugettext as _
PUSH_SYSTEM_USER_PERIOD_LOCK_KEY = "PUSH_SYSTEM_USER_PERIOD_KEY"
PUSH_SYSTEM_USER_PERIOD_TASK_NAME = _("PUSH SYSTEM USER TO CLUSTER PERIOD TASK")
# PUSH_SYSTEM_USER_PERIOD_LOCK_KEY = "PUSH_SYSTEM_USER_PERIOD_KEY"
PUSH_SYSTEM_USER_PERIOD_TASK_NAME = _("PUSH SYSTEM USER TO CLUSTER PERIOD: {}")
PUSH_SYSTEM_USER_MANUAL_TASK_NAME = _("PUSH SYSTEM USER TO CLUSTER MANUALLY: {}")
PUSH_SYSTEM_USER_TASK_NAME = _("PUSH SYSTEM USER TO CLUSTER: {}")
PUSH_SYSTEM_USER_LOCK_KEY = "PUSH_SYSTEM_USER_TO_CLUSTER_LOCK_{}"
# PUSH_SYSTEM_USER_LOCK_KEY = "PUSH_SYSTEM_USER_TO_CLUSTER_LOCK_{}"
PUSH_SYSTEM_USER_ON_CHANGE_TASK_NAME = _("PUSH SYSTEM USER ON CHANGE: {}")
PUSH_SYSTEM_USER_ON_CREATE_TASK_NAME = _("PUSH SYSTEM USER ON CREATE: {}")
PUSH_SYSTEM_USERS_ON_ASSET_CREATE_TASK_NAME = _("PUSH SYSTEM USERS ON ASSET CREAT: {}")
UPDATE_ASSETS_HARDWARE_TASK_NAME = _('UPDATE ASSETS HARDWARE INFO')
UPDATE_ASSETS_HARDWARE_PERIOD_LOCK_KEY = "UPDATE_ASSETS_HARDWARE_PERIOD_LOCK_KEY"
UPDATE_ASSETS_HARDWARE_MANUAL_TASK_NAME = _('UPDATE ASSETS HARDWARE INFO MANUALLY')
UPDATE_ASSETS_HARDWARE_ON_CREATE_TASK_NAME = _('UPDATE ASSETS HARDWARE INFO ON CREATE')
# UPDATE_ASSETS_HARDWARE_PERIOD_LOCK_KEY = "UPDATE_ASSETS_HARDWARE_PERIOD_LOCK_KEY"
UPDATE_ASSETS_HARDWARE_PERIOD_TASK_NAME = _('UPDATE ASSETS HARDWARE INFO PERIOD')
UPDATE_ASSETS_HARDWARE_TASKS = [
{
......@@ -20,10 +26,10 @@ UPDATE_ASSETS_HARDWARE_TASKS = [
}
]
TEST_ADMIN_USER_CONN_PERIOD_LOCK_KEY = "TEST_ADMIN_USER_CONN_PERIOD_KEY"
TEST_ADMIN_USER_CONN_PERIOD_TASK_NAME = _("TEST ADMIN USER CONN PERIOD TASK")
# TEST_ADMIN_USER_CONN_PERIOD_LOCK_KEY = "TEST_ADMIN_USER_CONN_PERIOD_KEY"
TEST_ADMIN_USER_CONN_PERIOD_TASK_NAME = _("TEST ADMIN USER CONN PERIOD: {}")
TEST_ADMIN_USER_CONN_MANUAL_TASK_NAME = _("TEST ADMIN USER CONN MANUALLY: {}")
TEST_ADMIN_USER_CONN_TASK_NAME = _("TEST ADMIN USER CONN: {}")
TEST_ADMIN_USER_CONN_LOCK_KEY = TEST_ADMIN_USER_CONN_TASK_NAME
ADMIN_USER_CONN_CACHE_KEY = "ADMIN_USER_CONN_{}"
TEST_ADMIN_USER_CONN_TASKS = [
{
......@@ -38,10 +44,8 @@ ASSET_ADMIN_CONN_CACHE_KEY = "ASSET_ADMIN_USER_CONN_{}"
TEST_ASSET_CONN_TASK_NAME = _("ASSET CONN TEST MANUAL")
TEST_SYSTEM_USER_CONN_PERIOD_LOCK_KEY = "TEST_SYSTEM_USER_CONN_PERIOD_KEY"
TEST_SYSTEM_USER_CONN_PERIOD_TASK_NAME = _("TEST SYSTEM USER CONN PERIOD TASK")
TEST_SYSTEM_USER_CONN_CACHE_KEY_PREFIX = "SYSTEM_USER_CONN_"
TEST_SYSTEM_USER_CONN_TASK_NAME = _("TEST SYSTEM USER CONN: {}")
TEST_SYSTEM_USER_CONN_LOCK_KEY = "TEST_SYSTEM_USER_CONN_{}"
TEST_SYSTEM_USER_CONN_PERIOD_TASK_NAME = _("TEST SYSTEM USER CONN PERIOD: {}")
TEST_SYSTEM_USER_CONN_MANUAL_TASK_NAME = _("TEST SYSTEM USER CONN MANUALLY: {}")
SYSTEM_USER_CONN_CACHE_KEY = "SYSTEM_USER_CONN_{}"
TEST_SYSTEM_USER_CONN_TASKS = [
{
......
......@@ -13,13 +13,14 @@ from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from common.utils import signer, ssh_key_string_to_obj, ssh_key_gen
from common.utils import get_signer, ssh_key_string_to_obj, ssh_key_gen
from .utils import private_key_validator
from ..const import SYSTEM_USER_CONN_CACHE_KEY
__all__ = ['AdminUser', 'SystemUser',]
logger = logging.getLogger(__name__)
signer = get_signer()
class AssetUser(models.Model):
......
此差异已折叠。
......@@ -49,9 +49,6 @@ $(document).ready(function(){
"aaSorting": [[2, "asc"]],
"aoColumnDefs": [ { "bSortable": false, "aTargets": [ 0 ] }],
"bAutoWidth": false,
"language": {
"url": "/static/js/plugins/dataTables/i18n/zh-hans.json"
},
columns: [
{data: "checkbox"},
{data: "id"},
......
......@@ -28,7 +28,7 @@ from common.utils import get_object_or_none, get_logger, is_uuid
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
from ..hands import AdminUserRequiredMixin
from ..tasks import update_assets_hardware_info
from ..tasks import update_assets_hardware_info_util
__all__ = [
......@@ -314,10 +314,6 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
except Exception as e:
failed.append('%s: %s' % (asset_dict['hostname'], str(e)))
if assets:
update_assets_hardware_info.delay([asset._to_secret_json() for asset in assets])
data = {
'created': created,
'created_info': 'Created {}'.format(len(created)),
......
# ~*~ coding: utf-8 ~*~
import os
import json
from functools import wraps
from celery import Celery
from celery import Celery, subtask
from celery.signals import worker_ready, worker_shutdown
from .utils import get_logger
logger = get_logger(__file__)
# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'jumpserver.settings')
......@@ -15,3 +22,167 @@ app = Celery('jumpserver')
# pickle the object when using Windows.
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks(lambda: [app_config.split('.')[0] for app_config in settings.INSTALLED_APPS])
def create_or_update_celery_periodic_tasks(tasks):
from django_celery_beat.models import PeriodicTask, IntervalSchedule, CrontabSchedule
"""
:param tasks: {
'add-every-monday-morning': {
'task': 'tasks.add' # A registered celery task,
'interval': 30,
'crontab': "30 7 * * *",
'args': (16, 16),
'kwargs': {},
'enabled': False,
},
}
:return:
"""
# Todo: check task valid, task and callback must be a celery task
for name, detail in tasks.items():
interval = None
crontab = None
if isinstance(detail.get("interval"), int):
intervals = IntervalSchedule.objects.filter(
every=detail["interval"], period=IntervalSchedule.SECONDS
)
if intervals:
interval = intervals[0]
else:
interval = IntervalSchedule.objects.create(
every=detail['interval'],
period=IntervalSchedule.SECONDS,
)
elif isinstance(detail.get("crontab"), str):
try:
minute, hour, day, month, week = detail["crontab"].split()
except ValueError:
raise SyntaxError("crontab is not valid")
kwargs = dict(
minute=minute, hour=hour, day_of_week=week,
day_of_month=day, month_of_year=month,
)
contabs = CrontabSchedule.objects.filter(
**kwargs
)
if contabs:
crontab = contabs[0]
else:
crontab = CrontabSchedule.objects.create(**kwargs)
else:
raise SyntaxError("Schedule is not valid")
defaults = dict(
interval=interval,
crontab=crontab,
name=name,
task=detail['task'],
args=json.dumps(detail.get('args', [])),
kwargs=json.dumps(detail.get('kwargs', {})),
enabled=detail.get('enabled', True),
)
task = PeriodicTask.objects.update_or_create(
defaults=defaults, name=name,
)
return task
def disable_celery_periodic_task(task_name):
from django_celery_beat.models import PeriodicTask
PeriodicTask.objects.filter(name=task_name).update(enabled=False)
def delete_celery_periodic_task(task_name):
from django_celery_beat.models import PeriodicTask
PeriodicTask.objects.filter(name=task_name).delete()
__REGISTER_PERIODIC_TASKS = []
__AFTER_APP_SHUTDOWN_CLEAN_TASKS = []
__AFTER_APP_READY_RUN_TASKS = []
def register_as_period_task(crontab=None, interval=None):
"""
Warning: Task must be have not any args and kwargs
:param crontab: "* * * * *"
:param interval: 60*60*60
:return:
"""
if crontab is None and interval is None:
raise SyntaxError("Must set crontab or interval one")
def decorate(func):
if crontab is None and interval is None:
raise SyntaxError("Interval and crontab must set one")
# Because when this decorator run, the task was not created,
# So we can't use func.name
name = '{func.__module__}.{func.__name__}'.format(func=func)
if name not in __REGISTER_PERIODIC_TASKS:
create_or_update_celery_periodic_tasks({
name: {
'task': name,
'interval': interval,
'crontab': crontab,
'args': (),
'enabled': True,
}
})
__REGISTER_PERIODIC_TASKS.append(name)
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
return decorate
def after_app_ready_start(func):
# Because when this decorator run, the task was not created,
# So we can't use func.name
name = '{func.__module__}.{func.__name__}'.format(func=func)
if name not in __AFTER_APP_READY_RUN_TASKS:
__AFTER_APP_READY_RUN_TASKS.append(name)
@wraps(func)
def decorate(*args, **kwargs):
return func(*args, **kwargs)
return decorate
def after_app_shutdown_clean(func):
# Because when this decorator run, the task was not created,
# So we can't use func.name
name = '{func.__module__}.{func.__name__}'.format(func=func)
if name not in __AFTER_APP_READY_RUN_TASKS:
__AFTER_APP_SHUTDOWN_CLEAN_TASKS.append(name)
@wraps(func)
def decorate(*args, **kwargs):
return func(*args, **kwargs)
return decorate
@worker_ready.connect
def on_app_ready(sender=None, headers=None, body=None, **kwargs):
logger.debug("App ready signal recv")
logger.debug("Start need start task: [{}]".format(
", ".join(__AFTER_APP_READY_RUN_TASKS))
)
for task in __AFTER_APP_READY_RUN_TASKS:
subtask(task).delay()
@worker_shutdown.connect
def after_app_shutdown(sender=None, headers=None, body=None, **kwargs):
from django_celery_beat.models import PeriodicTask
logger.debug("App shutdown signal recv")
logger.debug("Clean need cleaned period tasks: [{}]".format(
', '.join(__AFTER_APP_SHUTDOWN_CLEAN_TASKS))
)
PeriodicTask.objects.filter(name__in=__AFTER_APP_SHUTDOWN_CLEAN_TASKS).delete()
from django.core.mail import send_mail
from django.conf import settings
from common import celery_app as app
from .celery import app
from .utils import get_logger
......
# -*- coding: utf-8 -*-
#
import json
import re
from collections import OrderedDict
from six import string_types
import base64
import os
from itertools import chain
import string
import logging
import datetime
import time
......@@ -27,9 +25,6 @@ from django.conf import settings
from django.utils import timezone
from .compat import to_bytes, to_string
SECRET_KEY = settings.SECRET_KEY
UUID_PATTERN = re.compile(r'[0-9a-zA-Z\-]{36}')
......@@ -51,9 +46,22 @@ def get_object_or_none(model, **kwargs):
return obj
class Signer(object):
class Singleton(type):
def __init__(cls, *args, **kwargs):
cls.__instance = None
super().__init__(*args, **kwargs)
def __call__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = super().__call__(*args, **kwargs)
return cls.__instance
else:
return cls.__instance
class Signer(metaclass=Singleton):
"""用来加密,解密,和基于时间戳的方式验证token"""
def __init__(self, secret_key=SECRET_KEY):
def __init__(self, secret_key=None):
self.secret_key = secret_key
def sign(self, value):
......@@ -100,58 +108,10 @@ def combine_seq(s1, s2, callback=None):
return seq
def search_object_attr(obj, value='', attr_list=None, ignore_case=False):
"""It's provide a method to search a object attribute equal some value
If object some attribute equal :param: value, return True else return False
class A():
name = 'admin'
age = 7
:param obj: A object
:param value: A string match object attribute
:param attr_list: Only match attribute in attr_list
:param ignore_case: Ignore case
:return: Boolean
"""
if value == '':
return True
try:
object_attr = obj.__dict__
except AttributeError:
return False
if attr_list is not None:
new_object_attr = {}
for attr in attr_list:
new_object_attr[attr] = object_attr.pop(attr)
object_attr = new_object_attr
if ignore_case:
if not isinstance(value, string_types):
return False
if value.lower() in map(string.lower, map(str, object_attr.values())):
return True
else:
if value in object_attr.values():
return True
return False
def get_logger(name=None):
return logging.getLogger('jumpserver.%s' % name)
def int_seq(seq):
try:
return map(int, seq)
except ValueError:
return seq
def timesince(dt, since='', default="just now"):
"""
Returns string representing "time since" e.g.
......@@ -391,4 +351,6 @@ def is_uuid(s):
return False
signer = Signer()
def get_signer():
signer = Signer(settings.SECRET_KEY)
return signer
......@@ -337,8 +337,9 @@ CELERY_ACCEPT_CONTENT = ['json', 'pickle']
CELERY_RESULT_EXPIRES = 3600
CELERY_WORKER_LOG_FORMAT = '%(asctime)s [%(module)s %(levelname)s] %(message)s'
CELERY_WORKER_TASK_LOG_FORMAT = '%(asctime)s [%(module)s %(levelname)s] %(message)s'
CELERY_TASK_EAGER_PROPAGATES = True
CELERY_TIMEZONE = TIME_ZONE
# TERMINAL_HEATBEAT_INTERVAL = CONFIG.TERMINAL_HEATBEAT_INTERVAL or 30
# CELERY_ENABLE_UTC = True
# Cache use redis
......
# -*- coding: utf-8 -*-
#
from functools import wraps
TASK_PREFIX = "TOOT"
CALLBACK_PREFIX = "COC"
def register_as_period_task(crontab=None, interval=None):
"""
:param crontab: "* * * * *"
:param interval: 60*60*60
:return:
"""
from .utils import create_or_update_celery_periodic_tasks
if crontab is None and interval is None:
raise SyntaxError("Must set crontab or interval one")
def decorate(func):
@wraps(func)
def wrapper(*args, **kwargs):
tasks = {
func.__name__: {
'task': func.__name__,
'args': args,
'kwargs': kwargs,
'interval': interval,
'crontab': crontab,
'enabled': True,
}
}
create_or_update_celery_periodic_tasks(tasks)
return func(*args, **kwargs)
return wrapper
return decorate
......@@ -9,7 +9,9 @@ from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django_celery_beat.models import CrontabSchedule, IntervalSchedule, PeriodicTask
from common.utils import signer, get_logger
from common.utils import get_signer, get_logger
from common.celery import delete_celery_periodic_task, create_or_update_celery_periodic_tasks, \
disable_celery_periodic_task
from .ansible import AdHocRunner, AnsibleError
from .inventory import JMSInventory
......@@ -17,6 +19,7 @@ __all__ = ["Task", "AdHoc", "AdHocRunHistory"]
logger = get_logger(__file__)
signer = get_signer()
class Task(models.Model):
......@@ -82,8 +85,6 @@ class Task(models.Model):
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
from .utils import create_or_update_celery_periodic_tasks, \
disable_celery_periodic_task
from .tasks import run_ansible_task
super().save(
force_insert=force_insert, force_update=force_update,
......@@ -114,7 +115,6 @@ class Task(models.Model):
disable_celery_periodic_task(self.name)
def delete(self, using=None, keep_parents=False):
from .utils import delete_celery_periodic_task
super().delete(using=using, keep_parents=keep_parents)
delete_celery_periodic_task(self.name)
......@@ -246,7 +246,7 @@ class AdHoc(models.Model):
}
:return:
"""
self._become = signer.sign(json.dumps(item))
self._become = signer.sign(json.dumps(item)).decode('utf-8')
@property
def options(self):
......@@ -271,6 +271,11 @@ class AdHoc(models.Model):
except AdHocRunHistory.DoesNotExist:
return None
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
super().save(force_insert=force_insert, force_update=force_update,
using=using, update_fields=update_fields)
def __str__(self):
return "{} of {}".format(self.task.name, self.short_id)
......
......@@ -21,9 +21,9 @@ def run_ansible_task(task_id, callback=None, **kwargs):
task = get_object_or_none(Task, id=task_id)
if task:
result = task.object.run()
result = task.run()
if callback is not None:
subtask(callback).delay(result)
subtask(callback).delay(result, task_name=task.name)
return result
else:
logger.error("No task found")
......
......@@ -57,14 +57,20 @@
<td class="text-center">{{ object.adhoc.all | length}}</td>
<td class="text-center">{{ object.latest_adhoc.hosts | length}}</td>
<td class="text-center">
{% if object.latest_history.is_success %}
<i class="fa fa-check text-navy"></i>
{% else %}
<i class="fa fa-times text-danger"></i>
{% if object.latest_history %}
{% if object.latest_history.is_success %}
<i class="fa fa-check text-navy"></i>
{% else %}
<i class="fa fa-times text-danger"></i>
{% endif %}
{% endif %}
</td>
<td class="text-center">{{ object.latest_history.date_start }}</td>
<td class="text-center">{{ object.latest_history.timedelta|floatformat }} s</td>
<td class="text-center">
{% if object.latest_history %}
{{ object.latest_history.timedelta|floatformat }} s
{% endif %}
</td>
<td class="text-center">
<a href="{% url 'ops:task-run' pk=object.id %}" class="btn btn-xs btn-info">{% trans "Run" %}</a>
<a data-uid="{{ object.id }}" class="btn btn-xs btn-danger btn-del">{% trans "Delete" %}</a>
......
# ~*~ coding: utf-8 ~*~
import json
from django_celery_beat.models import PeriodicTask, IntervalSchedule, CrontabSchedule
from common.utils import get_logger, get_object_or_none
from .models import Task, AdHoc
......@@ -13,22 +9,27 @@ def get_task_by_id(task_id):
return get_object_or_none(Task, id=task_id)
def create_or_update_ansible_task(
task_name, hosts, tasks, pattern='all', options=None,
def update_or_create_ansible_task(
task_name, hosts, tasks,
interval=None, crontab=None, is_periodic=False,
callback=None, pattern='all', options=None,
run_as_admin=False, run_as="", become_info=None,
created_by=None, interval=None, crontab=None,
is_periodic=False, callback=None,
created_by=None,
):
task = get_object_or_none(Task, name=task_name)
defaults = {
'name': task_name,
'interval': interval,
'crontab': crontab,
'is_periodic': is_periodic,
'callback': callback,
'created_by': created_by,
}
if task is None:
task = Task(
name=task_name, interval=interval,
crontab=crontab, is_periodic=is_periodic,
callback=callback, created_by=created_by
)
task.save()
created = False
task, _ = Task.objects.update_or_create(
defaults=defaults, name=task_name,
)
adhoc = task.latest_adhoc
new_adhoc = AdHoc(task=task, pattern=pattern,
......@@ -38,70 +39,13 @@ def create_or_update_ansible_task(
new_adhoc.tasks = tasks
new_adhoc.options = options
new_adhoc.become = become_info
if not adhoc or adhoc != new_adhoc:
logger.debug("Task create new adhoc: {}".format(task_name))
new_adhoc.save()
task.latest_adhoc = new_adhoc
return task
def create_or_update_celery_periodic_tasks(tasks):
"""
:param tasks: {
'add-every-monday-morning': {
'task': 'tasks.add' # A registered celery task,
'interval': 30,
'crontab': "30 7 * * *",
'args': (16, 16),
'kwargs': {},
'enabled': False,
},
}
:return:
"""
# Todo: check task valid, task and callback must be a celery task
for name, detail in tasks.items():
interval = None
crontab = None
if isinstance(detail.get("interval"), int):
interval, _ = IntervalSchedule.objects.get_or_create(
every=detail['interval'],
period=IntervalSchedule.SECONDS,
)
elif isinstance(detail.get("crontab"), str):
try:
minute, hour, day, month, week = detail["crontab"].split()
except ValueError:
raise SyntaxError("crontab is not valid")
crontab, _ = CrontabSchedule.objects.get_or_create(
minute=minute, hour=hour, day_of_week=week,
day_of_month=day, month_of_year=month,
)
else:
raise SyntaxError("Schedule is not valid")
defaults = dict(
interval=interval,
crontab=crontab,
name=name,
task=detail['task'],
args=json.dumps(detail.get('args', [])),
kwargs=json.dumps(detail.get('kwargs', {})),
enabled=detail['enabled']
)
task = PeriodicTask.objects.update_or_create(
defaults=defaults, name=name,
)
logger.info("Create periodic task: {}".format(task))
return task
def disable_celery_periodic_task(task_name):
PeriodicTask.objects.filter(name=task_name).update(enabled=False)
created = True
return task, created
def delete_celery_periodic_task(task_name):
PeriodicTask.objects.filter(name=task_name).delete()
......@@ -262,9 +262,6 @@ jumpserver.initDataTable = function (options) {
var table = ele.DataTable({
pageLength: options.pageLength || 15,
dom: options.dom || '<"#uc.pull-left">flt<"row m-t"<"col-md-8"<"#op.col-md-6"><"col-md-6 text-center"i>><"col-md-4"p>>',
language: {
url: options.i18n_url || "/static/js/plugins/dataTables/i18n/zh-hans.json"
},
order: options.order || [],
select: options.select || 'multi',
buttons: [],
......
......@@ -2,7 +2,7 @@
<div class="sidebar-collapse">
<ul class="nav" id="side-menu">
{% include '_user_profile.html' %}
{% if request.user.is_superuser and request.COOKIES.admin == "Yes" %}
{% if request.user.is_superuser and request.COOKIES.IN_ADMIN_PAGE != "No" %}
{% include '_nav.html' %}
{% else %}
{% include '_nav_user.html' %}
......
......@@ -20,7 +20,7 @@
<li><a href="{% url 'users:user-profile-update' %}">{% trans 'Profile settings' %}</a></li>
<li class="divider"></li>
{% if request.user.is_superuser %}
{% if request.COOKIES.admin == 'No' %}
{% if request.COOKIES.IN_ADMIN_PAGE == 'No' %}
<li><a id="switch_admin">{% trans 'Admin page' %}</a></li>
{% else %}
<li><a id="switch_user">{% trans 'User page' %}</a></li>
......@@ -37,11 +37,11 @@
$(document).ready(function () {
})
.on('click', '#switch_admin', function () {
setCookie("admin", "Yes");
setCookie("IN_ADMIN_PAGE", "Yes");
window.location = "/"
})
.on('click', '#switch_user', function () {
setCookie("admin", "No");
setCookie("IN_ADMIN_PAGE", "No");
window.location = "/"
})
</script>
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from __future__ import unicode_literals
import uuid
from django.db import models, IntegrityError
from django.contrib.auth.models import Group
from django.utils.translation import ugettext_lazy as _
from common.utils import signer, date_expired_default
from common.mixins import NoDeleteModelMixin
__all__ = ['UserGroup']
......
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
import os
import uuid
from collections import OrderedDict
......@@ -15,10 +14,11 @@ from django.utils import timezone
from django.shortcuts import reverse
from .group import UserGroup
from common.utils import signer, date_expired_default
from common.utils import get_signer, date_expired_default
__all__ = ['User']
signer = get_signer()
class User(AbstractUser):
......
......@@ -5,10 +5,12 @@ from django.utils.translation import ugettext_lazy as _
from rest_framework import serializers
from rest_framework_bulk import BulkListSerializer
from common.utils import signer, validate_ssh_public_key
from common.utils import get_signer, validate_ssh_public_key
from common.mixins import BulkSerializerMixin
from .models import User, UserGroup
signer = get_signer()
class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
groups_display = serializers.SerializerMethodField()
......
......@@ -45,7 +45,7 @@ def start_beat():
os.chdir(APPS_DIR)
os.environ.setdefault('PYTHONOPTIMIZE', '1')
scheduler = "django_celery_beat.schedulers:DatabaseScheduler"
cmd = 'celery -A common beat -l {} --scheduler {} --max-interval 30 '.format(LOG_LEVEL, scheduler)
cmd = 'celery -A common beat -l {} --scheduler {} --max-interval 5 '.format(LOG_LEVEL, scheduler)
subprocess.call(cmd, shell=True)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册