mirror of https://github.com/jumpserver/jumpserver
feat: 支持定时任务
parent
223814f897
commit
d0de36358c
|
@ -0,0 +1,28 @@
|
||||||
|
# Generated by Django 3.2.14 on 2022-11-18 06:31
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('ops', '0032_auto_20221117_1848'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='job',
|
||||||
|
name='crontab',
|
||||||
|
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Regularly perform'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='job',
|
||||||
|
name='interval',
|
||||||
|
field=models.IntegerField(blank=True, default=24, null=True, verbose_name='Cycle perform'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='job',
|
||||||
|
name='is_periodic',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
|
@ -9,14 +9,16 @@ from django.utils.translation import gettext_lazy as _
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from celery import current_task
|
from celery import current_task
|
||||||
|
|
||||||
|
from common.const.choices import Trigger
|
||||||
from common.db.models import BaseCreateUpdateModel
|
from common.db.models import BaseCreateUpdateModel
|
||||||
|
|
||||||
__all__ = ["Job", "JobExecution"]
|
__all__ = ["Job", "JobExecution"]
|
||||||
|
|
||||||
from ops.ansible import JMSInventory, AdHocRunner, PlaybookRunner
|
from ops.ansible import JMSInventory, AdHocRunner, PlaybookRunner
|
||||||
|
from ops.mixin import PeriodTaskModelMixin
|
||||||
|
|
||||||
|
|
||||||
class Job(BaseCreateUpdateModel):
|
class Job(BaseCreateUpdateModel, PeriodTaskModelMixin):
|
||||||
class Types(models.TextChoices):
|
class Types(models.TextChoices):
|
||||||
adhoc = 'adhoc', _('Adhoc')
|
adhoc = 'adhoc', _('Adhoc')
|
||||||
playbook = 'playbook', _('Playbook')
|
playbook = 'playbook', _('Playbook')
|
||||||
|
@ -48,6 +50,42 @@ class Job(BaseCreateUpdateModel):
|
||||||
parameters_define = models.JSONField(default=dict, verbose_name=_('Parameters define'))
|
parameters_define = models.JSONField(default=dict, verbose_name=_('Parameters define'))
|
||||||
comment = models.CharField(max_length=1024, default='', verbose_name=_('Comment'), null=True, blank=True)
|
comment = models.CharField(max_length=1024, default='', verbose_name=_('Comment'), null=True, blank=True)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def last_execution(self):
|
||||||
|
return self.executions.last()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def date_last_run(self):
|
||||||
|
return self.last_execution.date_created if self.last_execution else None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def summary(self):
|
||||||
|
summary = {
|
||||||
|
"total": 0,
|
||||||
|
"success": 0,
|
||||||
|
}
|
||||||
|
for execution in self.executions.all():
|
||||||
|
summary["total"] += 1
|
||||||
|
if execution.is_success:
|
||||||
|
summary["success"] += 1
|
||||||
|
return summary
|
||||||
|
|
||||||
|
@property
|
||||||
|
def average_time_cost(self):
|
||||||
|
total_cost = 0
|
||||||
|
finished_count = self.executions.filter(status__in=['success', 'failed']).count()
|
||||||
|
for execution in self.executions.filter(status__in=['success', 'failed']).all():
|
||||||
|
total_cost += execution.time_cost
|
||||||
|
return total_cost / finished_count if finished_count else 0
|
||||||
|
|
||||||
|
def get_register_task(self):
|
||||||
|
from ..tasks import run_ops_job
|
||||||
|
name = "run_ops_job_period_{}".format(str(self.id)[:8])
|
||||||
|
task = run_ops_job.name
|
||||||
|
args = (str(self.id),)
|
||||||
|
kwargs = {}
|
||||||
|
return name, task, args, kwargs
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def inventory(self):
|
def inventory(self):
|
||||||
return JMSInventory(self.assets.all(), self.runas_policy, self.runas)
|
return JMSInventory(self.assets.all(), self.runas_policy, self.runas)
|
||||||
|
@ -72,7 +110,10 @@ class JobExecution(BaseCreateUpdateModel):
|
||||||
def get_runner(self):
|
def get_runner(self):
|
||||||
inv = self.job.inventory
|
inv = self.job.inventory
|
||||||
inv.write_to_file(self.inventory_path)
|
inv.write_to_file(self.inventory_path)
|
||||||
extra_vars = json.loads(self.parameters)
|
if isinstance(self.parameters, str):
|
||||||
|
extra_vars = json.loads(self.parameters)
|
||||||
|
else:
|
||||||
|
extra_vars = {}
|
||||||
|
|
||||||
if self.job.type == 'adhoc':
|
if self.job.type == 'adhoc':
|
||||||
runner = AdHocRunner(
|
runner = AdHocRunner(
|
||||||
|
|
|
@ -2,24 +2,26 @@ from django.db import transaction
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from common.drf.fields import ReadableHiddenField
|
from common.drf.fields import ReadableHiddenField
|
||||||
|
from ops.mixin import PeriodTaskSerializerMixin
|
||||||
from ops.models import Job, JobExecution
|
from ops.models import Job, JobExecution
|
||||||
|
|
||||||
_all_ = []
|
_all_ = []
|
||||||
|
|
||||||
|
|
||||||
class JobSerializer(serializers.ModelSerializer):
|
class JobSerializer(serializers.ModelSerializer, PeriodTaskSerializerMixin):
|
||||||
owner = ReadableHiddenField(default=serializers.CurrentUserDefault())
|
owner = ReadableHiddenField(default=serializers.CurrentUserDefault())
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Job
|
model = Job
|
||||||
fields = [
|
read_only_fields = ["id", "date_last_run", "date_created", "date_updated", "average_time_cost"]
|
||||||
"id", "name", "instant", "type", "module", "args", "playbook", "assets", "runas_policy", "runas", "owner",
|
fields = read_only_fields + [
|
||||||
|
"name", "instant", "type", "module", "args", "playbook", "assets", "runas_policy", "runas", "owner",
|
||||||
"parameters_define",
|
"parameters_define",
|
||||||
"timeout",
|
"timeout",
|
||||||
"chdir",
|
"chdir",
|
||||||
"comment",
|
"comment",
|
||||||
"date_created",
|
"summary",
|
||||||
"date_updated"
|
"is_periodic", "interval", "crontab"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
@shared_task(soft_time_limit=60, queue="ansible", verbose_name=_("Run ansible task"))
|
@shared_task(soft_time_limit=60, queue="ansible", verbose_name=_("Run ansible task"))
|
||||||
def run_ops_job(job_id, **kwargs):
|
def run_ops_job(job_id):
|
||||||
job = get_object_or_none(Job, id=job_id)
|
job = get_object_or_none(Job, id=job_id)
|
||||||
execution = job.create_execution()
|
execution = job.create_execution()
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue