jumpserver/apps/ops/serializers/job.py

128 lines
5.0 KiB
Python

import uuid
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from assets.models import Asset, Node
from common.serializers import WritableNestedModelSerializer
from common.serializers.fields import ReadableHiddenField, ObjectRelatedField
from ops.mixin import PeriodTaskSerializerMixin
from ops.models import Job, JobExecution
from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from ops.serializers import JobVariableSerializer
class JobSerializer(BulkOrgResourceModelSerializer, PeriodTaskSerializerMixin, WritableNestedModelSerializer):
creator = ReadableHiddenField(default=serializers.CurrentUserDefault())
run_after_save = serializers.BooleanField(label=_("Execute after saving"), default=False, required=False)
date_last_run = serializers.DateTimeField(label=_('Date last run'), read_only=True)
name = serializers.CharField(label=_('Name'), max_length=128, allow_blank=True, required=False)
assets = serializers.PrimaryKeyRelatedField(label=_('Assets'), queryset=Asset.objects, many=True, required=False)
nodes = ObjectRelatedField(label=_('Nodes'), queryset=Node.objects, many=True, required=False)
variable = JobVariableSerializer(many=True, required=False, allow_null=True, label=_('Variable'))
parameters = serializers.JSONField(label=_('Parameters'), default={}, write_only=True, required=False,
allow_null=True)
def to_internal_value(self, data):
instant = data.get('instant', False)
job_type = data.get('type', '')
_uid = str(uuid.uuid4()).split('-')[-1]
if instant:
data['name'] = f'job-{_uid}'
if job_type == 'upload_file':
data['name'] = f'upload_file-{_uid}'
return super().to_internal_value(data)
def get_request_user(self):
request = self.context.get('request')
user = request.user if request else None
return user
def get_periodic_variable(self, variables):
periodic_variable = {}
for variable in variables:
periodic_variable[variable['var_name']] = variable['default_value']
return periodic_variable
def validate(self, attrs):
attrs = super().validate(attrs)
if attrs.get('is_periodic') is True:
attrs['periodic_variable'] = self.get_periodic_variable(attrs.get('variable', []))
return attrs
class Meta:
model = Job
read_only_fields = [
"id", "date_last_run", "date_created",
"date_updated", "average_time_cost", "created_by", "material"
]
fields_m2m = ['variable']
fields = read_only_fields + [
"name", "instant", "type", "module",
"args", "playbook", "assets",
"runas_policy", "runas", "creator",
"use_parameter_define", "parameters_define",
"timeout", "chdir", "comment", "summary",
"is_periodic", "interval", "crontab", "nodes",
"run_after_save", "parameters", "periodic_variable"
] + fields_m2m
extra_kwargs = {
'average_time_cost': {'label': _('Duration')},
}
class FileSerializer(serializers.Serializer):
files = serializers.FileField(allow_empty_file=False, max_length=128)
class Meta:
ref_name = "JobFileSerializer"
class JobTaskStopSerializer(serializers.Serializer):
task_id = serializers.CharField(max_length=128)
class Meta:
ref_name = "JobTaskStopSerializer"
class JobExecutionSerializer(BulkOrgResourceModelSerializer):
creator = ReadableHiddenField(default=serializers.CurrentUserDefault())
job_type = serializers.ReadOnlyField(label=_("Job type"))
material = serializers.ReadOnlyField(label=_("Command"))
is_success = serializers.ReadOnlyField(label=_("Is success"))
is_finished = serializers.ReadOnlyField(label=_("Is finished"))
time_cost = serializers.ReadOnlyField(label=_("Time cost"))
class Meta:
model = JobExecution
read_only_fields = ["id", "task_id", "timedelta", "time_cost",
'is_finished', 'date_start', 'date_finished',
'date_created', 'is_success', 'job_type',
'summary', 'material']
fields = read_only_fields + [
"job", "parameters", "creator"
]
extra_kwargs = {
"task_id": {
"label": _("Task id"),
},
"job": {
"label": _("Job"),
}
}
def validate_job(self, job_obj):
if job_obj.creator != self.context['request'].user:
raise serializers.ValidationError(_("You do not have permission for the current job."))
return job_obj
@staticmethod
def validate_parameters(parameters):
prefix = "jms_"
new_parameters = {}
for key, value in parameters.items():
if not key.startswith("jms_"):
key = prefix + key
new_parameters[key] = value
return new_parameters