mirror of https://github.com/jumpserver/jumpserver
[Change] 修改一些view
parent
c940a4c0fb
commit
b60e5a7ee3
|
@ -112,7 +112,12 @@ class Asset(models.Model):
|
||||||
'groups': [group.name for group in self.groups.all()],
|
'groups': [group.name for group in self.groups.all()],
|
||||||
'username': self.admin_user.username if self.admin_user else '',
|
'username': self.admin_user.username if self.admin_user else '',
|
||||||
'password': self.admin_user.password if self.admin_user else '',
|
'password': self.admin_user.password if self.admin_user else '',
|
||||||
'private_key': self.admin_user.private_key if self.admin_user else None,
|
'private_key': self.admin_user.private_key_file if self.admin_user else None,
|
||||||
|
'become': {
|
||||||
|
'method': self.admin_user.become_method,
|
||||||
|
'user': self.admin_user.become_user,
|
||||||
|
'pass': self.admin_user.become_pass,
|
||||||
|
} if self.admin_user.become else {},
|
||||||
}
|
}
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -3,12 +3,14 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
from hashlib import md5
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
from common.utils import signer, validate_ssh_private_key, ssh_key_string_to_obj
|
from common.utils import signer, validate_ssh_private_key, ssh_key_string_to_obj
|
||||||
|
|
||||||
|
@ -38,7 +40,7 @@ class AdminUser(models.Model):
|
||||||
become = models.BooleanField(default=True)
|
become = models.BooleanField(default=True)
|
||||||
become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4)
|
become_method = models.CharField(choices=BECOME_METHOD_CHOICES, default='sudo', max_length=4)
|
||||||
become_user = models.CharField(default='root', max_length=64)
|
become_user = models.CharField(default='root', max_length=64)
|
||||||
become_password = models.CharField(default='', max_length=128)
|
become_pass = models.CharField(default='', max_length=128)
|
||||||
_public_key = models.CharField(
|
_public_key = models.CharField(
|
||||||
max_length=4096, blank=True, verbose_name=_('SSH public key'))
|
max_length=4096, blank=True, verbose_name=_('SSH public key'))
|
||||||
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
||||||
|
@ -74,6 +76,18 @@ class AdminUser(models.Model):
|
||||||
def private_key(self, private_key_raw):
|
def private_key(self, private_key_raw):
|
||||||
self._private_key = signer.sign(private_key_raw)
|
self._private_key = signer.sign(private_key_raw)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def private_key_file(self):
|
||||||
|
if not self.private_key:
|
||||||
|
return None
|
||||||
|
project_dir = settings.PROJECT_DIR
|
||||||
|
tmp_dir = os.path.join(project_dir, 'tmp')
|
||||||
|
key_name = md5(self._private_key).hexdigest()
|
||||||
|
key_path = os.path.join(tmp_dir, key_name)
|
||||||
|
if not os.path.exists(key_path):
|
||||||
|
self.private_key.write_private_key_file(key_path)
|
||||||
|
return key_path
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def public_key(self):
|
def public_key(self):
|
||||||
return signer.unsign(self._public_key)
|
return signer.unsign(self._public_key)
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
{% extends '_base_list.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% load static %}
|
||||||
|
{% block content_left_head %}
|
||||||
|
<link href="{% static 'css/plugins/datepicker/datepicker3.css' %}" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
#search_btn {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block table_search %}
|
||||||
|
<form id="search_form" method="get" action="" class="pull-right form-inline">
|
||||||
|
<div class="form-group" id="date">
|
||||||
|
<div class="input-daterange input-group" id="datepicker">
|
||||||
|
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
|
||||||
|
<input type="text" class="input-sm form-control" style="width: 100px;" name="date_from" value="{{ date_from }}">
|
||||||
|
<span class="input-group-addon">to</span>
|
||||||
|
<input type="text" class="input-sm form-control" style="width: 100px;" name="date_to" value="{{ date_to }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<select class="select2 form-control" name="username">
|
||||||
|
<option value="">{% trans 'User' %}</option>
|
||||||
|
{% for user in user_list %}
|
||||||
|
<option value="{{ user }}" {% if user == username %} selected {% endif %}>{{ user }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<select class="select2 form-control" name="ip">
|
||||||
|
<option value="">{% trans 'Asset' %}</option>
|
||||||
|
{% for asset in asset_list %}
|
||||||
|
<option value="{{ asset }}" {% if asset == ip %} selected {% endif %}>{{ asset }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<select class="select2 form-control" name="system_user">
|
||||||
|
<option value="">{% trans 'System user' %}</option>
|
||||||
|
{% for su in system_user_list %}
|
||||||
|
<option value="{{ su }}" {% if su == system_user %} selected {% endif %}>{{ su }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" class="form-control input-sm" name="keyword" placeholder="Keyword" value="{{ keyword }}">
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<div class="input-group-btn">
|
||||||
|
<button id='search_btn' type="submit" class="btn btn-sm btn-primary">
|
||||||
|
搜索
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block table_head %}
|
||||||
|
<th class="text-center"></th>
|
||||||
|
<th class="text-center">{% trans 'ID' %}</th>
|
||||||
|
<th class="text-center">{% trans 'User' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Asset' %}</th>
|
||||||
|
<th class="text-center">{% trans 'System user' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Terminal' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Command' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Success' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Finished' %}</th>
|
||||||
|
<th class="text-center">{% trans 'R/M' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Date start' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Time' %}</th>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block table_body %}
|
||||||
|
{% for proxy_log in proxy_log_list %}
|
||||||
|
<tr class="gradeX">
|
||||||
|
<td class="text-center"><input type="checkbox" class="cbx-term" value="{{ proxy_log.id }}"></td>
|
||||||
|
<td class="text-center">
|
||||||
|
<a href="{% url 'audits:proxy-log-detail' pk=proxy_log.id %}">{{ proxy_log.id }}</a>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">{{ proxy_log.user }}</td>
|
||||||
|
<td class="text-center">{{ proxy_log.asset }}</td>
|
||||||
|
<td class="text-center">{{ proxy_log.system_user }}</td>
|
||||||
|
<td class="text-center">{{ proxy_log.terminal }}</td>
|
||||||
|
<td class="text-center">{{ proxy_log.commands.all|length}}</td>
|
||||||
|
<td class="text-center">
|
||||||
|
{% if proxy_log.is_failed %}
|
||||||
|
<i class="fa fa-times text-danger"></i>
|
||||||
|
{% else %}
|
||||||
|
<i class="fa fa-check text-navy"></i>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
{% if proxy_log.is_finished %}
|
||||||
|
<td class="text-center">
|
||||||
|
<i class="fa fa-check text-navy"></i>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<a><span class="text-navy"><i class="fa fa-play-circle"></i></span></a>
|
||||||
|
</td>
|
||||||
|
{% else %}
|
||||||
|
<td class="text-center">
|
||||||
|
<a class="btn-term" value="{{ proxy_log.id }}"><i class="fa fa-times text-danger"></i></a>
|
||||||
|
</td>
|
||||||
|
<td class="text-center">
|
||||||
|
<a><span class="text-danger"><i class="fa fa-eye"></i></span></a>
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
<td class="text-center">{{ proxy_log.date_start }}</td>
|
||||||
|
<td class="text-center">{{ proxy_log.date_finished|timeuntil:proxy_log.date_start }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content_bottom_left %}
|
||||||
|
<div id="actions">
|
||||||
|
<div class="input-group">
|
||||||
|
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
|
||||||
|
<option value="terminate">{% trans 'Terminate selected' %}</option>
|
||||||
|
</select>
|
||||||
|
<div class="input-group-btn pull-left" style="padding-left: 5px;">
|
||||||
|
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
|
||||||
|
{% trans 'Submit' %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block custom_foot_js %}
|
||||||
|
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
|
||||||
|
<script>
|
||||||
|
function terminateConnection(data) {
|
||||||
|
function success() {
|
||||||
|
window.setTimeout(function () {
|
||||||
|
window.location.reload()
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
var the_url = "{% url 'api-applications:terminate-connection' %}";
|
||||||
|
APIUpdateAttr({url: the_url, method: 'POST', body: JSON.stringify(data), success: success, success_message: 'Terminate success'});
|
||||||
|
}
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('table').DataTable({
|
||||||
|
"searching": false,
|
||||||
|
"paging": false,
|
||||||
|
"bInfo" : false,
|
||||||
|
"order": []
|
||||||
|
});
|
||||||
|
$('.select2').select2();
|
||||||
|
$('#date .input-daterange').datepicker({
|
||||||
|
dateFormat: 'mm/dd/yy',
|
||||||
|
keyboardNavigation: false,
|
||||||
|
forceParse: false,
|
||||||
|
autoclose: true
|
||||||
|
});
|
||||||
|
}).on('click', '.btn-term', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var proxy_log_id = $this.attr('value');
|
||||||
|
var data = {
|
||||||
|
proxy_log_id: proxy_log_id
|
||||||
|
};
|
||||||
|
terminateConnection(data)
|
||||||
|
}).on('click', '#btn_bulk_update', function () {
|
||||||
|
var data = [];
|
||||||
|
$('.cbx-term:checked').each(function () {
|
||||||
|
data.push({proxy_log_id: $(this).attr('value')})
|
||||||
|
});
|
||||||
|
terminateConnection(data)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -4,14 +4,16 @@ from .. import views
|
||||||
app_name = 'audits'
|
app_name = 'audits'
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^proxy-log$', views.ProxyLogListView.as_view(),
|
url(r'^proxy-log-offline/$', views.ProxyLogOfflineListView.as_view(),
|
||||||
name='proxy-log-list'),
|
name='proxy-log-offline-list'),
|
||||||
url(r'^proxy-log/(?P<pk>\d+)$', views.ProxyLogDetailView.as_view(),
|
url(r'^proxy-log-online/$', views.ProxyLogOnlineListView.as_view(),
|
||||||
|
name='proxy-log-online-list'),
|
||||||
|
url(r'^proxy-log/(?P<pk>\d+)/$', views.ProxyLogDetailView.as_view(),
|
||||||
name='proxy-log-detail'),
|
name='proxy-log-detail'),
|
||||||
# url(r'^proxy-log/(?P<pk>\d+)/commands$', views.ProxyLogCommandsListView.as_view(), name='proxy-log-commands-list'),
|
# url(r'^proxy-log/(?P<pk>\d+)/commands$', views.ProxyLogCommandsListView.as_view(), name='proxy-log-commands-list'),
|
||||||
url(r'^command-log$', views.CommandLogListView.as_view(),
|
url(r'^command-log/$', views.CommandLogListView.as_view(),
|
||||||
name='command-log-list'),
|
name='command-log-list'),
|
||||||
url(r'^login-log$', views.LoginLogListView.as_view(),
|
url(r'^login-log/$', views.LoginLogListView.as_view(),
|
||||||
name='login-log-list'),
|
name='login-log-list'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ from audits.backends import CommandLogSerializer
|
||||||
|
|
||||||
class ProxyLogListView(AdminUserRequiredMixin, ListView):
|
class ProxyLogListView(AdminUserRequiredMixin, ListView):
|
||||||
model = ProxyLog
|
model = ProxyLog
|
||||||
template_name = 'audits/proxy_log_list.html'
|
template_name = 'audits/proxy_log_online_list.html'
|
||||||
context_object_name = 'proxy_log_list'
|
context_object_name = 'proxy_log_list'
|
||||||
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
|
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
|
||||||
keyword = user = asset = system_user = date_from_s = date_to_s = ''
|
keyword = user = asset = system_user = date_from_s = date_to_s = ''
|
||||||
|
@ -89,6 +89,38 @@ class ProxyLogListView(AdminUserRequiredMixin, ListView):
|
||||||
return super(ProxyLogListView, self).get_context_data(**kwargs)
|
return super(ProxyLogListView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyLogOfflineListView(ProxyLogListView):
|
||||||
|
template_name = 'audits/proxy_log_online_list.html'
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super(ProxyLogOfflineListView, self).get_queryset()
|
||||||
|
queryset = queryset.filter(is_finished=True)
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = {
|
||||||
|
'action': _('Proxy log offline list'),
|
||||||
|
}
|
||||||
|
kwargs.update(context)
|
||||||
|
return super(ProxyLogOfflineListView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyLogOnlineListView(ProxyLogListView):
|
||||||
|
template_name = 'audits/proxy_log_online_list.html'
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super(ProxyLogOnlineListView, self).get_queryset()
|
||||||
|
queryset = queryset.filter(is_finished=False)
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = {
|
||||||
|
'action': _('Proxy log online list'),
|
||||||
|
}
|
||||||
|
kwargs.update(context)
|
||||||
|
return super(ProxyLogOnlineListView, self).get_context_data(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class ProxyLogDetailView(AdminUserRequiredMixin,
|
class ProxyLogDetailView(AdminUserRequiredMixin,
|
||||||
SingleObjectMixin,
|
SingleObjectMixin,
|
||||||
ListView):
|
ListView):
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
from collections import OrderedDict
|
||||||
from six import string_types
|
from six import string_types
|
||||||
import base64
|
import base64
|
||||||
import os
|
import os
|
||||||
|
@ -53,6 +54,7 @@ def get_object_or_none(model, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
class Signer(object):
|
class Signer(object):
|
||||||
|
"""用来加密,解密,和基于时间戳的方式验证token"""
|
||||||
def __init__(self, secret_key=SECRET_KEY):
|
def __init__(self, secret_key=SECRET_KEY):
|
||||||
self.secret_key = secret_key
|
self.secret_key = secret_key
|
||||||
|
|
||||||
|
@ -330,13 +332,13 @@ def encrypt_password(password):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
from collections import OrderedDict
|
|
||||||
|
|
||||||
|
|
||||||
def capacity_convert(size, expect='auto', rate=1000):
|
def capacity_convert(size, expect='auto', rate=1000):
|
||||||
"""
|
"""
|
||||||
:param cap: '100MB', '1G'
|
:param size: '100MB', '1G'
|
||||||
:param expect: 'K, M, G, T
|
:param expect: 'K, M, G, T
|
||||||
|
:param rate: Default 1000, may be 1024
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
rate_mapping = (
|
rate_mapping = (
|
||||||
|
|
|
@ -21,16 +21,16 @@ class JMSHost(Host):
|
||||||
# 添加密码和秘钥
|
# 添加密码和秘钥
|
||||||
if asset.get('password'):
|
if asset.get('password'):
|
||||||
self.set_variable('ansible_ssh_pass', asset['password'])
|
self.set_variable('ansible_ssh_pass', asset['password'])
|
||||||
if asset.get('key'):
|
if asset.get('private_key'):
|
||||||
self.set_variable('ansible_ssh_private_key_file', asset['private_key'])
|
self.set_variable('ansible_ssh_private_key_file', asset['private_key'])
|
||||||
|
|
||||||
# 添加become支持
|
# 添加become支持
|
||||||
become = asset.get("become", None)
|
become = asset.get("become", False)
|
||||||
if become is not None:
|
if become:
|
||||||
self.set_variable("ansible_become", True)
|
self.set_variable("ansible_become", True)
|
||||||
self.set_variable("ansible_become_method", become.get('method'))
|
self.set_variable("ansible_become_method", become.get('method', 'sudo'))
|
||||||
self.set_variable("ansible_become_user", become.get('user'))
|
self.set_variable("ansible_become_user", become.get('user', 'root'))
|
||||||
self.set_variable("ansible_become_pass", become.get('pass'))
|
self.set_variable("ansible_become_pass", become.get('pass', ''))
|
||||||
else:
|
else:
|
||||||
self.set_variable("ansible_become", False)
|
self.set_variable("ansible_become", False)
|
||||||
|
|
||||||
|
|
|
@ -265,8 +265,10 @@ class AdHocRunner(object):
|
||||||
result['success'].append(host)
|
result['success'].append(host)
|
||||||
|
|
||||||
for host, msgs in self.results_callback.result_q['dark'].items():
|
for host, msgs in self.results_callback.result_q['dark'].items():
|
||||||
msg = '\n'.join(['{}: {}'.format(msg.get('invocation', {}).get('module_name'),
|
msg = '\n'.join(['{} {}: {}'.format(
|
||||||
msg.get('msg', '')) for msg in msgs])
|
msg.get('module_stdout', ''),
|
||||||
|
msg.get('invocation', {}).get('module_name'),
|
||||||
|
msg.get('msg', '')) for msg in msgs])
|
||||||
result['failed'].append((host, msg))
|
result['failed'].append((host, msg))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,17 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{% trans 'Is success ' %}:</td>
|
<td>{% trans 'Is success ' %}:</td>
|
||||||
|
{% if object.is_finished %}
|
||||||
<td><b>{{ object.is_success|yesno:"Yes,No,Unkown" }}</b></td>
|
<td><b>{{ object.is_success|yesno:"Yes,No,Unkown" }}</b></td>
|
||||||
|
{% else %}
|
||||||
|
<td>
|
||||||
|
<div class="progress progress-striped active">
|
||||||
|
<div style="width: 50%" aria-valuemax="100" aria-valuemin="0" aria-valuenow="75" role="progressbar" class="progress-bar progress-bar-danger">
|
||||||
|
<span class="sr-only">40% Complete (success)</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>{% trans 'Assets ' %}:</td>
|
<td>{% trans 'Assets ' %}:</td>
|
||||||
|
@ -84,6 +94,31 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="ibox float-e-margins">
|
||||||
|
<div class="ibox-title">
|
||||||
|
<span><b>Result</b></span>
|
||||||
|
<div class="ibox-tools">
|
||||||
|
<a class="collapse-link">
|
||||||
|
<i class="fa fa-chevron-up"></i>
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||||
|
<i class="fa fa-wrench"></i>
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu dropdown-user">
|
||||||
|
</ul>
|
||||||
|
<a class="close-link">
|
||||||
|
<i class="fa fa-times"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ibox-content">
|
||||||
|
<pre>
|
||||||
|
{{ object.result }}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||||
<div class="panel panel-danger">
|
<div class="panel panel-danger">
|
||||||
|
|
|
@ -18,7 +18,7 @@ logger = get_logger(__file__)
|
||||||
def run_AdHoc(task_tuple, assets,
|
def run_AdHoc(task_tuple, assets,
|
||||||
task_name='Ansible AdHoc runner',
|
task_name='Ansible AdHoc runner',
|
||||||
task_id=None, pattern='all',
|
task_id=None, pattern='all',
|
||||||
record=True, verbose=False):
|
record=True, verbose=True):
|
||||||
"""
|
"""
|
||||||
:param task_tuple: (('module_name', 'module_args'), ('module_name', 'module_args'))
|
:param task_tuple: (('module_name', 'module_args'), ('module_name', 'module_args'))
|
||||||
:param assets: [asset1, asset2]
|
:param assets: [asset1, asset2]
|
||||||
|
@ -51,6 +51,11 @@ def run_AdHoc(task_tuple, assets,
|
||||||
else:
|
else:
|
||||||
record = Task.objects.get(uuid=task_id)
|
record = Task.objects.get(uuid=task_id)
|
||||||
record.date_start = timezone.now()
|
record.date_start = timezone.now()
|
||||||
|
record.date_finished = None
|
||||||
|
record.timedelta = None
|
||||||
|
record.is_finished = False
|
||||||
|
record.is_success = False
|
||||||
|
record.save()
|
||||||
ts_start = time.time()
|
ts_start = time.time()
|
||||||
if verbose:
|
if verbose:
|
||||||
logger.debug('Start runner {}'.format(task_name))
|
logger.debug('Start runner {}'.format(task_name))
|
||||||
|
@ -61,7 +66,7 @@ def run_AdHoc(task_tuple, assets,
|
||||||
record.date_finished = timezone.now()
|
record.date_finished = timezone.now()
|
||||||
record.is_finished = True
|
record.is_finished = True
|
||||||
if verbose:
|
if verbose:
|
||||||
record.result = json.dumps(result)
|
record.result = json.dumps(result, indent=4, sort_keys=True)
|
||||||
record.summary = json.dumps(summary)
|
record.summary = json.dumps(summary)
|
||||||
record.timedelta = timedelta
|
record.timedelta = timedelta
|
||||||
if len(summary['failed']) == 0:
|
if len(summary['failed']) == 0:
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# ~*~ coding: utf-8 ~*~
|
# ~*~ coding: utf-8 ~*~
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
import time
|
||||||
import json
|
import json
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
@ -81,4 +82,5 @@ class TaskRunView(View):
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
pk = kwargs.get(self.pk_url_kwarg)
|
pk = kwargs.get(self.pk_url_kwarg)
|
||||||
rerun_task.delay(pk)
|
rerun_task.delay(pk)
|
||||||
|
time.sleep(0.5)
|
||||||
return redirect(reverse('ops:task-detail', kwargs={'pk': pk}))
|
return redirect(reverse('ops:task-detail', kwargs={'pk': pk}))
|
||||||
|
|
|
@ -35,10 +35,10 @@ def push_users(self, assets, users):
|
||||||
('authorized_key', "user={} state=present key='{}'".format(
|
('authorized_key', "user={} state=present key='{}'".format(
|
||||||
user['username'], user['public_key'])),
|
user['username'], user['public_key'])),
|
||||||
('lineinfile',
|
('lineinfile',
|
||||||
"name=/etc/sudoers state=present regexp='^{0} ALL=(ALL)' "
|
"dest=/etc/sudoers state=present regexp='^{0} ALL=' "
|
||||||
"line='{0} ALL=(ALL) NOPASSWD: {1}' "
|
"line='{0} ALL=(ALL) NOPASSWD: {1}' "
|
||||||
"validate='visudo -cf %s'".format(
|
"validate='visudo -cf %s'".format(
|
||||||
user['username'], user.get('sudo', '/bin/whoami')
|
user['username'], user.get('sudo', '/sbin/ifconfig')
|
||||||
))
|
))
|
||||||
])
|
])
|
||||||
task_name = 'Push user {}'.format(','.join([user['name'] for user in users]))
|
task_name = 'Push user {}'.format(','.join([user['name'] for user in users]))
|
||||||
|
|
|
@ -56,8 +56,11 @@
|
||||||
<li id="audits">
|
<li id="audits">
|
||||||
<a href="#"><i class="fa fa-files-o"></i> <span class="nav-label">{% trans 'Audits' %}</span><span class="fa arrow"></span></a>
|
<a href="#"><i class="fa fa-files-o"></i> <span class="nav-label">{% trans 'Audits' %}</span><span class="fa arrow"></span></a>
|
||||||
<ul class="nav nav-second-level">
|
<ul class="nav nav-second-level">
|
||||||
<li id="proxy-log">
|
<li id="proxy-log-offline">
|
||||||
<a href="{% url 'audits:proxy-log-list' %}">{% trans 'Proxy log' %}</a>
|
<a href="{% url 'audits:proxy-log-offline-list' %}">{% trans 'Session online' %}</a>
|
||||||
|
</li>
|
||||||
|
<li id="proxy-log-online">
|
||||||
|
<a href="{% url 'audits:proxy-log-online-list' %}">{% trans 'Session history' %}</a>
|
||||||
</li>
|
</li>
|
||||||
<li id="command-log">
|
<li id="command-log">
|
||||||
<a href="{% url 'audits:command-log-list' %}">{% trans 'Command log' %}</a>
|
<a href="{% url 'audits:command-log-list' %}">{% trans 'Command log' %}</a>
|
||||||
|
|
Loading…
Reference in New Issue