From 9ba792cf1cd337912905fb2035f1270b36cd3021 Mon Sep 17 00:00:00 2001 From: Aaron3S Date: Mon, 26 Dec 2022 19:02:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20ops=20=E6=94=AF=E6=8C=81=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E5=92=8C=E8=B5=84=E4=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/ops/ansible/runner.py | 4 +++- apps/ops/api/job.py | 14 +++++++++++++- apps/ops/models/job.py | 16 ++++++++++++++-- apps/ops/serializers/job.py | 14 +++++++++++++- apps/ops/urls/api_urls.py | 1 + 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/apps/ops/ansible/runner.py b/apps/ops/ansible/runner.py index 13d56bd00..8c7517ade 100644 --- a/apps/ops/ansible/runner.py +++ b/apps/ops/ansible/runner.py @@ -13,7 +13,8 @@ class AdHocRunner: "reboot", 'shutdown', 'poweroff', 'halt', 'dd', 'half', 'top' ] - def __init__(self, inventory, module, module_args='', pattern='*', project_dir='/tmp/', extra_vars={}): + def __init__(self, inventory, module, module_args='', pattern='*', project_dir='/tmp/', extra_vars={}, + dry_run=False): self.id = uuid.uuid4() self.inventory = inventory self.pattern = pattern @@ -23,6 +24,7 @@ class AdHocRunner: self.cb = DefaultCallback() self.runner = None self.extra_vars = extra_vars + self.dry_run = dry_run def check_module(self): if self.module not in self.cmd_modules_choices: diff --git a/apps/ops/api/job.py b/apps/ops/api/job.py index 0cf8ade0c..1c7cac33d 100644 --- a/apps/ops/api/job.py +++ b/apps/ops/api/job.py @@ -1,3 +1,4 @@ +from django.db.models import Count from rest_framework.views import APIView from django.shortcuts import get_object_or_404 from rest_framework.response import Response @@ -5,12 +6,14 @@ from rest_framework.response import Response from ops.models import Job, JobExecution from ops.serializers.job import JobSerializer, JobExecutionSerializer -__all__ = ['JobViewSet', 'JobExecutionViewSet', 'JobRunVariableHelpAPIView', 'JobAssetDetail', 'JobExecutionTaskDetail'] +__all__ = ['JobViewSet', 'JobExecutionViewSet', 'JobRunVariableHelpAPIView', + 'JobAssetDetail', 'JobExecutionTaskDetail','FrequentUsernames'] from ops.tasks import run_ops_job_execution from ops.variables import JMS_JOB_VARIABLE_HELP from orgs.mixins.api import OrgBulkModelViewSet from orgs.utils import tmp_to_org, get_current_org_id, get_current_org +from assets.models import Account def set_task_to_serializer_data(serializer, task): @@ -111,3 +114,12 @@ class JobExecutionTaskDetail(APIView): 'is_success': execution.is_success, 'time_cost': execution.time_cost, }) + + +class FrequentUsernames(APIView): + rbac_perms = () + permission_classes = () + + def get(self, request, **kwargs): + top_accounts = Account.objects.all().values('username').annotate(total=Count('username')).order_by('total') + return Response(data=top_accounts) diff --git a/apps/ops/models/job.py b/apps/ops/models/job.py index c83038f80..1b6a33b59 100644 --- a/apps/ops/models/job.py +++ b/apps/ops/models/job.py @@ -166,6 +166,10 @@ class JobExecution(JMSOrgBaseModel): return result = self.current_job.args result += " chdir={}".format(self.current_job.chdir) + + if self.current_job.module in ['python']: + result += " executable={}".format(self.current_job.module) + print(result) return self.job.args def get_runner(self): @@ -187,9 +191,17 @@ class JobExecution(JMSOrgBaseModel): if self.current_job.type == 'adhoc': args = self.compile_shell() + module = "shell" + if self.current_job.module not in ['python']: + module = self.current_job.module + runner = AdHocRunner( - self.inventory_path, self.current_job.module, module_args=args, - pattern="all", project_dir=self.private_dir, extra_vars=extra_vars, + self.inventory_path, + module, + module_args=args, + pattern="all", + project_dir=self.private_dir, + extra_vars=extra_vars, ) elif self.current_job.type == 'playbook': runner = PlaybookRunner( diff --git a/apps/ops/serializers/job.py b/apps/ops/serializers/job.py index 386c4e92f..4b6ea82d1 100644 --- a/apps/ops/serializers/job.py +++ b/apps/ops/serializers/job.py @@ -1,5 +1,7 @@ from django.utils.translation import ugettext as _ from rest_framework import serializers + +from assets.models import Node from common.drf.fields import ReadableHiddenField from ops.mixin import PeriodTaskSerializerMixin from ops.models import Job, JobExecution @@ -10,6 +12,16 @@ from orgs.mixins.serializers import BulkOrgResourceModelSerializer class JobSerializer(BulkOrgResourceModelSerializer, PeriodTaskSerializerMixin): creator = ReadableHiddenField(default=serializers.CurrentUserDefault()) run_after_save = serializers.BooleanField(label=_("Run after save"), default=False, required=False) + nodes = serializers.ListField(required=False, child=serializers.CharField()) + + def create(self, validated_data): + assets = validated_data.__getitem__('assets') + node_ids = validated_data.pop('nodes') + if node_ids: + nodes = Node.objects.filter(id__in=node_ids) + assets.extend( + Node.get_nodes_all_assets(*nodes).exclude(id__in=[asset.id for asset in assets])) + return super().create(validated_data) class Meta: model = Job @@ -22,7 +34,7 @@ class JobSerializer(BulkOrgResourceModelSerializer, PeriodTaskSerializerMixin): "chdir", "comment", "summary", - "is_periodic", "interval", "crontab", "run_after_save" + "is_periodic", "interval", "crontab", "run_after_save", "nodes" ] diff --git a/apps/ops/urls/api_urls.py b/apps/ops/urls/api_urls.py index 20f581b1d..5d859b801 100644 --- a/apps/ops/urls/api_urls.py +++ b/apps/ops/urls/api_urls.py @@ -26,6 +26,7 @@ urlpatterns = [ path('variables/help/', api.JobRunVariableHelpAPIView.as_view(), name='variable-help'), path('job-execution/asset-detail/', api.JobAssetDetail.as_view(), name='asset-detail'), path('job-execution/task-detail/', api.JobExecutionTaskDetail.as_view(), name='task-detail'), + path('frequent-username/', api.FrequentUsernames.as_view(), name='frequent-usernames'), path('ansible/job-execution//log/', api.AnsibleTaskLogApi.as_view(), name='job-execution-log'), path('celery/task//task-execution//log/', api.CeleryTaskExecutionLogApi.as_view(),