主機管理+堡壘機系統開發:批量任務開發思路(十一)

1、批量任務開發思路

一、開發目標

二、開發思路

一、前端提交發起請求100臺機器,那我要等待5分鐘,html

問題就在於,這100臺不是同時執行完的,有可能我有10臺執行完了,執行完了不能讓他等五分鐘,讓他執行完了馬上就返回前端

二、返回一個什麼呢?python

task_id的值,這個值是惟一值數據庫

三、觸發任務和拿取結果關聯起來?json

你至關於第一次提交是要觸發這個任務,觸發完這個任務後,不想讓頁面卡主,因此阿賈克斯必需要當即返回後端

你每隔10秒鐘去後臺取次結果,你再去後臺取就是發的新的請求,框架

觸發完任務後給它返回一個task_id的值,這個值是惟一值,我來後端取的時候拿上task_id的值ide

四、問題是如今結果存在哪?post

一、寫消息隊列,一個任務一個隊列,可能不合適,消息放到隊列取走就消失了,由於我想要結果永久保存

二、一個寫數據庫,每一個線程,把任務執行完了,本身寫到數據庫,我前端直接從數據庫裏那測試

2、批量任務存儲表結構

一、引子

一、日後臺提交一條任務,就往數據庫裏寫一條記錄,就把這個記錄的id返回

二、真正執行這條命令的主機從數據庫拿詳細的任務

三、一條大任務分出來不少子結果,因此你還要有一張表示存任務結果的

二、批量任務記錄表

class Task(models.Model):
    """批量任務記錄表"""
    user = models.ForeignKey("UserProfile")
    task_type_choices = ((0,'cmd'),(1,'file_transfer'))
    task_type = models.SmallIntegerField(choices=task_type_choices)
    content = models.TextField(verbose_name="任務內容")
    #hosts = models.ManyToManyField("BindHost")
    date  = models.DateTimeField(auto_now_add=True)
  1. 那個用戶執行的要不要存?
  2. 任務類型是批量執行命令仍是批量分發文件
  3. 執行任務的類型要不要存?
  4. 這個任務有沒有執行完,是用過什麼來肯定的?

三、子任務表

class TaskLogDetail(models.Model):
    task = models.ForeignKey("Task")
    bind_host = models.ForeignKey("BindHost")
    result = models.TextField()

    status_choices = ((0,'success'),(1,'failed'),(2,'init'))
    status = models.SmallIntegerField(choices=status_choices)

    start_date = models.DateTimeField(auto_now_add=True)
    end_date = models.DateTimeField(blank=True,null=True)


    def __str__(self):
        return "%s %s" %(self.bind_host,self.status)
  1. 寫清楚本身關聯是哪一個大的任務
  2. 執行每一個任務的時候,要不要寫清楚本身是那臺主機
  3. 每一個子任務執行是否成功是否是要存起來

四、admin註冊

admin.site.register(models.Task,TaskAdmin)
admin.site.register(models.TaskLogDetail,TaskLogDetailAdmin)

3、批量任務前端頁面開發

一、url

url(r'^multitask/cmd/$', views.multitask_cmd,name="multitask_cmd"),

二、views

@login_required
def multitask_cmd(request):

    return render(request,"multitask_cmd.html")

@login_required
def multitask_result(request):
    task_id = request.GET.get('task_id')
    task_obj = models.Task.objects.get(id=task_id)
    task_log_results = list(task_obj.tasklogdetail_set.values('id', 'result','status','start_date','end_date'))

    return  HttpResponse(json.dumps(task_log_results,default=json_date_handler))

三、multitask_cmd.html

{% extends 'index.html' %}


{% block page-title %}主機管理|批量命令{% endblock %}

{% block page-content %}
    {% csrf_token %}

<div class="row">

    {% include 'multitask_host_list_component.html' %}

    <div class="col-lg-8">
        <div class="panel">
            <div class="panel-heading">
                <h3 class="panel-title">命令操做</h3>
            </div>
            <div class="panel-body">
                <textarea id="cmd_text" class="form-control"></textarea>
                <input type="button" id='post_task_btn'  onclick="PostTask(this,'cmd')" class="btn btn-success pull-right" value="執行命令">
            </div>
        </div>
        <div class="panel">
            <div class="panel-heading">
                <h3 class="panel-title">任務結果</h3>
            </div>
            <div class="panel-body">
                <ul id="task_result_container"></ul>
            </div>
        </div>
    </div>

</div>


{% include 'multitask_js_component.html' %}

{% endblock %}

四、multitask_host_list_component.html

    <div class="col-lg-4">
        <div class="panel">
            <div class="panel-heading">
                <h3 class="panel-title">主機列表</h3>
            </div>
            <div class="panel-body">
                    <div class="list-group bord-no">
                        <a onclick="HostListDisplayToggle(this)" class="list-group-item " href="#">
                            <input type="checkbox" onclick="SelectGroup(this)">
                            未分組主機
                            <span class="badge badge-primary">{{ request.user.bind_hosts.count }}</span>
                        </a>
                        <ol class="hide">
                            {% for bind_host in request.user.bind_hosts.all %}
                                <li><input type="checkbox"  select_host="true" value="{{ bind_host.id }}">{{ bind_host.host.hostname }}({{ bind_host.host.ip_addr }})@{{ bind_host.remote_user.username}}</li>
                            {% endfor %}
                        </ol>



                        {% for host_group in request.user.host_groups.select_related %}

                            <a onclick="HostListDisplayToggle(this)" class="list-group-item " href="#">
                                <input type="checkbox" onclick="SelectGroup(this)">
                                {{ host_group.name }}
                                <span class="badge badge-primary">{{ host_group.bind_hosts.count }}</span>
                            </a>
                            <ol class="hide">
                                {% for bind_host in host_group.bind_hosts.all %}
                                    <li><input type="checkbox"  select_host="true" value="{{ bind_host.id }}">{{ bind_host.host.hostname }}({{ bind_host.host.ip_addr }})@{{ bind_host.remote_user.username}}</li>
                                {% endfor %}
                            </ol>


                        {% endfor %}
                    </div>
            </div>
        </div>

    </div>

4、前端測試截圖

 一、基本框架截圖

二、全選反選功能截圖

三、命令操做功能截圖

 四、整個框架完成截圖

五、控制檯批量執行命令截圖

相關文章
相關標籤/搜索