feat: Supports running adhoc,playbook with variable (#14417)

* perf:Create a job that supports adding node parameters

* feat: add variable model

* feat: Modify Variable and AdHoc models,

* feat: Parameters can be set when running job

* feat: Supports setting  variable type

* feat: Supports running adhoc with parameters

* feat: Supports running playbook with parameters

* fix: Translate

* feat: Support setting variables for scheduled tasks

* perf: Translate

---------

Co-authored-by: wangruidong <940853815@qq.com>
This commit is contained in:
fit2bot
2024-11-07 10:38:34 +08:00
committed by GitHub
parent 8f11167db0
commit c96ae1022b
30 changed files with 565 additions and 141 deletions

View File

@@ -4,3 +4,4 @@ from .adhoc import *
from .celery import *
from .job import *
from .playbook import *
from .variable import *

View File

@@ -22,6 +22,7 @@ from ops.models import Job, JobExecution
from ops.serializers.job import (
JobSerializer, JobExecutionSerializer, FileSerializer, JobTaskStopSerializer
)
from ops.utils import merge_nodes_and_assets
__all__ = [
'JobViewSet', 'JobExecutionViewSet', 'JobRunVariableHelpAPIView', 'JobExecutionTaskDetail', 'UsernameHintsAPI'
@@ -36,8 +37,6 @@ from accounts.models import Account
from assets.const import Protocol
from perms.const import ActionChoices
from perms.utils.asset_perm import PermAssetDetailUtil
from perms.models import PermNode
from perms.utils import UserPermAssetUtil
from jumpserver.settings import get_file_md5
@@ -47,26 +46,12 @@ def set_task_to_serializer_data(serializer, task_id):
setattr(serializer, "_data", data)
def merge_nodes_and_assets(nodes, assets, user):
if not nodes:
return assets
perm_util = UserPermAssetUtil(user=user)
for node_id in nodes:
if node_id == PermNode.FAVORITE_NODE_KEY:
node_assets = perm_util.get_favorite_assets()
elif node_id == PermNode.UNGROUPED_NODE_KEY:
node_assets = perm_util.get_ungroup_assets()
else:
_, node_assets = perm_util.get_node_all_assets(node_id)
assets.extend(node_assets.exclude(id__in=[asset.id for asset in assets]))
return assets
class JobViewSet(OrgBulkModelViewSet):
serializer_class = JobSerializer
filterset_fields = ('name', 'type')
search_fields = ('name', 'comment')
model = Job
_parameters = None
def check_permissions(self, request):
# job: upload_file
@@ -106,10 +91,10 @@ class JobViewSet(OrgBulkModelViewSet):
def perform_create(self, serializer):
run_after_save = serializer.validated_data.pop('run_after_save', False)
node_ids = serializer.validated_data.pop('nodes', [])
assets = serializer.validated_data.get('assets')
assets = merge_nodes_and_assets(node_ids, assets, self.request.user)
serializer.validated_data['assets'] = assets
self._parameters = serializer.validated_data.pop('parameters', None)
nodes = serializer.validated_data.pop('nodes', [])
assets = serializer.validated_data.get('assets', [])
assets = merge_nodes_and_assets(nodes, assets, self.request.user)
if serializer.validated_data.get('type') == Types.upload_file:
account_name = serializer.validated_data.get('runas')
self.check_upload_permission(assets, account_name)
@@ -126,6 +111,8 @@ class JobViewSet(OrgBulkModelViewSet):
def run_job(self, job, serializer):
execution = job.create_execution()
if self._parameters:
execution.parameters = JobExecutionSerializer.validate_parameters(self._parameters)
execution.creator = self.request.user
execution.save()
@@ -300,7 +287,7 @@ class UsernameHintsAPI(APIView):
permission_classes = [IsValidUser]
def post(self, request, **kwargs):
node_ids = request.data.get('nodes', None)
node_ids = request.data.get('nodes', [])
asset_ids = request.data.get('assets', [])
query = request.data.get('query', None)

25
apps/ops/api/variable.py Normal file
View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
from rest_framework.decorators import action
from rest_framework.response import Response
from common.api.generic import JMSModelViewSet
from common.const.http import OPTIONS, GET
from common.permissions import IsValidUser
from ..models import Variable
from ..serializers import VariableSerializer, VariableFormDataSerializer
__all__ = [
'VariableViewSet'
]
class VariableViewSet(JMSModelViewSet):
queryset = Variable.objects.all()
serializer_class = VariableSerializer
http_method_names = ['options', 'get']
@action(methods=[GET], detail=False, serializer_class=VariableFormDataSerializer,
permission_classes=[IsValidUser, ], url_path='form_data')
def form_data(self, request, *args, **kwargs):
# 只是为了动态返回serializer fields info
return Response({})