mirror of https://github.com/jumpserver/jumpserver
[Update] 完成树形改造
parent
c7296c2498
commit
c8728cace4
|
@ -1,73 +0,0 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
# Copyright (C) 2014-2018 Beijing DuiZhan Technology Co.,Ltd. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the GNU General Public License v2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from rest_framework import generics
|
||||
from rest_framework.response import Response
|
||||
from rest_framework_bulk import BulkModelViewSet
|
||||
|
||||
|
||||
from common.mixins import IDInFilterMixin
|
||||
from common.utils import get_logger
|
||||
from ..hands import IsSuperUser
|
||||
from ..models import Cluster
|
||||
from .. import serializers
|
||||
from ..tasks import test_admin_user_connectability_manual
|
||||
|
||||
|
||||
logger = get_logger(__file__)
|
||||
__all__ = [
|
||||
'ClusterViewSet', 'ClusterTestAssetsAliveApi', 'ClusterAddAssetsApi',
|
||||
]
|
||||
|
||||
|
||||
class ClusterViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||
"""
|
||||
Cluster api set, for add,delete,update,list,retrieve resource
|
||||
"""
|
||||
queryset = Cluster.objects.all()
|
||||
serializer_class = serializers.ClusterSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class ClusterTestAssetsAliveApi(generics.RetrieveAPIView):
|
||||
"""
|
||||
Test cluster asset can connect using admin user or not
|
||||
"""
|
||||
queryset = Cluster.objects.all()
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
def retrieve(self, request, *args, **kwargs):
|
||||
cluster = self.get_object()
|
||||
admin_user = cluster.admin_user
|
||||
test_admin_user_connectability_manual.delay(admin_user)
|
||||
return Response("Task has been send, seen left assets status")
|
||||
|
||||
|
||||
class ClusterAddAssetsApi(generics.UpdateAPIView):
|
||||
queryset = Cluster.objects.all()
|
||||
serializer_class = serializers.ClusterUpdateAssetsSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
cluster = self.get_object()
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if serializer.is_valid():
|
||||
assets = serializer.validated_data['assets']
|
||||
for asset in assets:
|
||||
asset.cluster = cluster
|
||||
asset.save()
|
||||
return Response({"msg": "ok"})
|
||||
else:
|
||||
return Response({'error': serializer.errors}, status=400)
|
|
@ -1,68 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ~*~ coding: utf-8 ~*~
|
||||
# Copyright (C) 2014-2018 Beijing DuiZhan Technology Co.,Ltd. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the GNU General Public License v2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.gnu.org/licenses/gpl-2.0.html
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from rest_framework import generics
|
||||
from rest_framework.response import Response
|
||||
from rest_framework_bulk import BulkModelViewSet
|
||||
from django.db.models import Count
|
||||
|
||||
from common.mixins import IDInFilterMixin
|
||||
from common.utils import get_logger
|
||||
from ..hands import IsSuperUser
|
||||
from ..models import AssetGroup
|
||||
from .. import serializers
|
||||
|
||||
|
||||
logger = get_logger(__file__)
|
||||
|
||||
__all__ = [
|
||||
'AssetGroupViewSet', 'GroupUpdateAssetsApi', 'GroupAddAssetsApi'
|
||||
]
|
||||
|
||||
|
||||
class AssetGroupViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||
"""
|
||||
Asset group api set, for add,delete,update,list,retrieve resource
|
||||
"""
|
||||
queryset = AssetGroup.objects.all().annotate(asset_count=Count("assets"))
|
||||
serializer_class = serializers.AssetGroupSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class GroupUpdateAssetsApi(generics.RetrieveUpdateAPIView):
|
||||
"""
|
||||
Asset group, update it's asset member
|
||||
"""
|
||||
queryset = AssetGroup.objects.all()
|
||||
serializer_class = serializers.GroupUpdateAssetsSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class GroupAddAssetsApi(generics.UpdateAPIView):
|
||||
queryset = AssetGroup.objects.all()
|
||||
serializer_class = serializers.GroupUpdateAssetsSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
group = self.get_object()
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if serializer.is_valid():
|
||||
assets = serializer.validated_data['assets']
|
||||
group.assets.add(*tuple(assets))
|
||||
return Response({"msg": "ok"})
|
||||
else:
|
||||
return Response({'error': serializer.errors}, status=400)
|
|
@ -13,6 +13,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from django.db import transaction
|
||||
from rest_framework import generics
|
||||
from rest_framework.response import Response
|
||||
from rest_framework_bulk import BulkModelViewSet
|
||||
|
@ -20,14 +21,14 @@ from rest_framework_bulk import BulkModelViewSet
|
|||
from common.mixins import IDInFilterMixin
|
||||
from common.utils import get_logger
|
||||
from ..hands import IsSuperUser
|
||||
from ..models import AdminUser
|
||||
from ..models import AdminUser, Asset
|
||||
from .. import serializers
|
||||
from ..tasks import test_admin_user_connectability_manual
|
||||
|
||||
|
||||
logger = get_logger(__file__)
|
||||
__all__ = [
|
||||
'AdminUserViewSet', 'AdminUserAddClustersApi', 'AdminUserTestConnectiveApi'
|
||||
'AdminUserViewSet', 'ReplaceNodesAdminUserApi', 'AdminUserTestConnectiveApi'
|
||||
]
|
||||
|
||||
|
||||
|
@ -40,19 +41,23 @@ class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet):
|
|||
permission_classes = (IsSuperUser,)
|
||||
|
||||
|
||||
class AdminUserAddClustersApi(generics.UpdateAPIView):
|
||||
class ReplaceNodesAdminUserApi(generics.UpdateAPIView):
|
||||
queryset = AdminUser.objects.all()
|
||||
serializer_class = serializers.AdminUserUpdateClusterSerializer
|
||||
serializer_class = serializers.ReplaceNodeAdminUserSerializer
|
||||
permission_classes = (IsSuperUser,)
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
admin_user = self.get_object()
|
||||
serializer = self.serializer_class(data=request.data)
|
||||
if serializer.is_valid():
|
||||
clusters = serializer.validated_data['clusters']
|
||||
for cluster in clusters:
|
||||
cluster.admin_user = admin_user
|
||||
cluster.save()
|
||||
nodes = serializer.validated_data['nodes']
|
||||
assets = []
|
||||
for node in nodes:
|
||||
assets.extend([asset.id for asset in node.get_all_assets()])
|
||||
|
||||
with transaction.atomic():
|
||||
Asset.objects.filter(id__in=assets).update(admin_user=admin_user)
|
||||
|
||||
return Response({"msg": "ok"})
|
||||
else:
|
||||
return Response({'error': serializer.errors}, status=400)
|
||||
|
|
|
@ -42,14 +42,11 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet):
|
|||
def get_queryset(self):
|
||||
queryset = super().get_queryset()
|
||||
admin_user_id = self.request.query_params.get('admin_user_id')
|
||||
system_user_id = self.request.query_params.get('system_user_id')
|
||||
node_id = self.request.query_params.get("node_id")
|
||||
|
||||
if admin_user_id:
|
||||
admin_user = get_object_or_404(AdminUser, id=admin_user_id)
|
||||
queryset = queryset.filter(admin_user=admin_user)
|
||||
if system_user_id:
|
||||
system_user = get_object_or_404(SystemUser, id=system_user_id)
|
||||
if node_id:
|
||||
node = get_object_or_404(Node, id=node_id)
|
||||
queryset = queryset.filter(nodes__key__startswith=node.key).distinct()
|
||||
|
|
|
@ -86,7 +86,7 @@ class AssetBulkUpdateForm(forms.ModelForm):
|
|||
class Meta:
|
||||
model = Asset
|
||||
fields = [
|
||||
'assets', 'port', 'labels', 'admin_user'
|
||||
'assets', 'port', 'admin_user', 'nodes',
|
||||
]
|
||||
widgets = {
|
||||
'admin_user': forms.SelectMultiple(
|
||||
|
@ -95,6 +95,9 @@ class AssetBulkUpdateForm(forms.ModelForm):
|
|||
'labels': forms.SelectMultiple(
|
||||
attrs={'class': 'select2', 'data-placeholder': _('Labels')}
|
||||
),
|
||||
'nodes': forms.SelectMultiple(
|
||||
attrs={'class': 'select2', 'data-placeholder': _('Nodes')}
|
||||
),
|
||||
}
|
||||
|
||||
def save(self, commit=True):
|
||||
|
|
|
@ -30,7 +30,7 @@ def default_cluster():
|
|||
|
||||
def default_node():
|
||||
try:
|
||||
from .tree import Node
|
||||
from .node import Node
|
||||
return Node.root()
|
||||
except:
|
||||
return None
|
||||
|
|
|
@ -17,7 +17,11 @@ class Node(models.Model):
|
|||
date_create = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.full_value
|
||||
return self.value
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self.value
|
||||
|
||||
@property
|
||||
def full_value(self):
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
from django.core.cache import cache
|
||||
from rest_framework import serializers
|
||||
from ..models import Cluster, AdminUser
|
||||
from ..models import Node, AdminUser
|
||||
from ..const import ADMIN_USER_CONN_CACHE_KEY
|
||||
|
||||
|
||||
|
@ -39,14 +39,14 @@ class AdminUserSerializer(serializers.ModelSerializer):
|
|||
return obj.assets_amount
|
||||
|
||||
|
||||
class AdminUserUpdateClusterSerializer(serializers.ModelSerializer):
|
||||
class ReplaceNodeAdminUserSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
管理用户更新关联到的集群
|
||||
"""
|
||||
clusters = serializers.PrimaryKeyRelatedField(
|
||||
many=True, queryset=Cluster.objects.all()
|
||||
nodes = serializers.PrimaryKeyRelatedField(
|
||||
many=True, queryset=Node.objects.all()
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = AdminUser
|
||||
fields = ['id', 'clusters']
|
||||
fields = ['id', 'nodes']
|
||||
|
|
|
@ -46,7 +46,7 @@ def set_assets_hardware_info(result, **kwargs):
|
|||
continue
|
||||
|
||||
___vendor = info.get('ansible_system_vendor', 'Unknown')
|
||||
___model = info.get('ansible_product_version', 'Unknown')
|
||||
___model = info.get('ansible_product_name', 'Unknown')
|
||||
___sn = info.get('ansible_product_serial', 'Unknown')
|
||||
|
||||
for ___cpu_model in info.get('ansible_processor', []):
|
||||
|
|
|
@ -1,280 +0,0 @@
|
|||
{% extends '_base_list.html' %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||
|
||||
{% endblock %}
|
||||
{% block content_left_head %}{% endblock %}
|
||||
|
||||
{% block table_search %}
|
||||
<div class="html5buttons">
|
||||
<div class="dt-buttons btn-group">
|
||||
<a class="btn btn-default btn_import" data-toggle="modal" data-target="#asset_import_modal" tabindex="0">
|
||||
<span>{% trans "Import" %}</span>
|
||||
</a>
|
||||
<a class="btn btn-default btn_export" tabindex="0">
|
||||
<span>{% trans "Export" %}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block table_container %}
|
||||
<div class="uc pull-left m-r-5"><a href="{% url "assets:asset-create" %}" class="btn btn-sm btn-primary"> {% trans "Create asset" %} </a></div>
|
||||
<div class="btn-group" style="float: right">
|
||||
<button data-toggle="dropdown" class="btn btn-default btn-sm dropdown-toggle">{% trans 'Label' %} <span class="caret"></span></button>
|
||||
<ul class="dropdown-menu labels">
|
||||
{% for label in labels %}
|
||||
<li><a style="font-weight: bolder">{{ label.name }}:{{ label.value }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<table class="table table-striped table-bordered table-hover " id="asset_list_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
|
||||
<th class="text-center">{% trans 'Hostname' %}</th>
|
||||
<th class="text-center">{% trans 'IP' %}</th>
|
||||
<th class="text-center">{% trans 'Port' %}</th>
|
||||
<th class="text-center">{% trans 'Cluster' %}</th>
|
||||
<th class="text-center">{% trans 'Hardware' %}</th>
|
||||
<th class="text-center">{% trans 'Active' %}</th>
|
||||
<th class="text-center">{% trans 'Reachable' %}</th>
|
||||
<th class="text-center">{% trans 'Action' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="actions" class="hide">
|
||||
<div class="input-group">
|
||||
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
|
||||
<option value="delete">{% trans 'Delete selected' %}</option>
|
||||
<option value="update">{% trans 'Update selected' %}</option>
|
||||
<option value="deactive">{% trans 'Deactive selected' %}</option>
|
||||
<option value="active">{% trans 'Active 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>
|
||||
{% include 'assets/_asset_import_modal.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block custom_foot_js %}
|
||||
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
function initTable() {
|
||||
var options = {
|
||||
ele: $('#asset_list_table'),
|
||||
columnDefs: [
|
||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||
{% url 'assets:asset-detail' pk=DEFAULT_PK as the_url %}
|
||||
var detail_btn = '<a href="{{ the_url }}">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||
}},
|
||||
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||
$(td).html(rowData.cluster_name)
|
||||
}},
|
||||
{targets: 5, createdCell: function (td, cellData, rowData) {
|
||||
$(td).html(rowData.hardware_info)
|
||||
}},
|
||||
{targets: 6, createdCell: function (td, cellData) {
|
||||
if (!cellData) {
|
||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||
} else {
|
||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
||||
}
|
||||
}},
|
||||
{targets: 7, createdCell: function (td, cellData) {
|
||||
if (cellData == 'Unknown'){
|
||||
$(td).html('<i class="fa fa-circle text-warning"></i>')
|
||||
} else if (!cellData) {
|
||||
$(td).html('<i class="fa fa-circle text-danger"></i>')
|
||||
} else {
|
||||
$(td).html('<i class="fa fa-circle text-navy"></i>')
|
||||
}
|
||||
}},
|
||||
{targets: 8, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = '<a href="{% url "assets:asset-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace("{{ DEFAULT_PK }}", cellData);
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
|
||||
$(td).html(update_btn + del_btn)
|
||||
}}
|
||||
],
|
||||
ajax_url: '{% url "api-assets:asset-list" %}',
|
||||
columns: [
|
||||
{data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "port" },
|
||||
{data: "cluster"},
|
||||
{data: "cpu_cores"}, {data: "is_active", orderable: false },
|
||||
{data: "is_connective", orderable: false}, {data: "id", orderable: false }
|
||||
],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
return jumpserver.initServerSideDataTable(options);
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
initTable();
|
||||
$(".select2").select2();
|
||||
})
|
||||
.on('click', '.labels li', function () {
|
||||
var val = $(this).text();
|
||||
$("#asset_list_table_filter input").val(val);
|
||||
jumpserver.table.search(val).draw();
|
||||
})
|
||||
.on('click', '.btn_export', function () {
|
||||
var $data_table = $('#asset_list_table').DataTable();
|
||||
var rows = $data_table.rows('.selected').data();
|
||||
var assets = [];
|
||||
$.each(rows, function (index, obj) {
|
||||
assets.push(obj.id)
|
||||
});
|
||||
$.ajax({
|
||||
url: "{% url "assets:asset-export" %}",
|
||||
method: 'POST',
|
||||
data: JSON.stringify({assets_id: assets}),
|
||||
dataType: "json",
|
||||
success: function (data, textStatus) {
|
||||
window.open(data.redirect)
|
||||
},
|
||||
error: function () {
|
||||
toastr.error('Export failed');
|
||||
}
|
||||
})
|
||||
})
|
||||
.on('click', '#btn_asset_import', function () {
|
||||
var $form = $('#fm_asset_import');
|
||||
$form.find('.help-block').remove();
|
||||
function success (data) {
|
||||
if (data.valid === false) {
|
||||
$('<span />', {class: 'help-block text-danger'}).html(data.msg).insertAfter($('#id_assets'));
|
||||
} else {
|
||||
$('#id_created').html(data.created_info);
|
||||
$('#id_created_detail').html(data.created.join(', '));
|
||||
$('#id_updated').html(data.updated_info);
|
||||
$('#id_updated_detail').html(data.updated.join(', '));
|
||||
$('#id_failed').html(data.failed_info);
|
||||
$('#id_failed_detail').html(data.failed.join(', '));
|
||||
var $data_table = $('#asset_list_table').DataTable();
|
||||
$data_table.ajax.reload();
|
||||
}
|
||||
}
|
||||
$form.ajaxSubmit({success: success});
|
||||
})
|
||||
|
||||
.on('click', '.btn_asset_delete', function () {
|
||||
var $this = $(this);
|
||||
var $data_table = $("#asset_list_table").DataTable();
|
||||
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||
var uid = $this.data('uid');
|
||||
var the_url = '{% url "api-assets:asset-detail" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", uid);
|
||||
objectDelete($this, name, the_url);
|
||||
setTimeout( function () {
|
||||
$data_table.ajax.reload();
|
||||
}, 3000);
|
||||
})
|
||||
.on('click', '#btn_bulk_update', function () {
|
||||
var action = $('#slct_bulk_update').val();
|
||||
var $data_table = $('#asset_list_table').DataTable();
|
||||
var id_list = [];
|
||||
$data_table.rows({selected: true}).every(function(){
|
||||
id_list.push(this.data().id);
|
||||
});
|
||||
if (id_list.length === 0) {
|
||||
return false;
|
||||
}
|
||||
var the_url = "{% url 'api-assets:asset-list' %}";
|
||||
|
||||
function doDeactive() {
|
||||
var data = [];
|
||||
$.each(id_list, function(index, object_id) {
|
||||
var obj = {"pk": object_id, "is_active": false};
|
||||
data.push(obj);
|
||||
});
|
||||
function success() {
|
||||
location.reload()
|
||||
}
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
success: success
|
||||
});
|
||||
}
|
||||
function doActive() {
|
||||
var data = [];
|
||||
$.each(id_list, function(index, object_id) {
|
||||
var obj = {"pk": object_id, "is_active": true};
|
||||
data.push(obj);
|
||||
});
|
||||
function success() {
|
||||
location.reload();
|
||||
}
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify(data),
|
||||
success: success
|
||||
});
|
||||
}
|
||||
function doDelete() {
|
||||
swal({
|
||||
title: "{% trans 'Are you sure?' %}",
|
||||
text: "{% trans 'This will delete the selected assets !!!' %}",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: "{% trans 'Confirm' %}",
|
||||
closeOnConfirm: false
|
||||
}, function() {
|
||||
var success = function() {
|
||||
var msg = "{% trans 'Asset Deleted.' %}";
|
||||
swal("{% trans 'Asset Delete' %}", msg, "success");
|
||||
$('#asset_list_table').DataTable().ajax.reload();
|
||||
};
|
||||
var fail = function() {
|
||||
var msg = "{% trans 'Asset Deleting failed.' %}";
|
||||
swal("{% trans 'Asset Delete' %}", msg, "error");
|
||||
};
|
||||
var url_delete = the_url + '?id__in=' + JSON.stringify(id_list);
|
||||
APIUpdateAttr({
|
||||
url: url_delete,
|
||||
method: 'DELETE',
|
||||
success: success,
|
||||
error: fail
|
||||
});
|
||||
$data_table.ajax.reload();
|
||||
jumpserver.checked = false;
|
||||
});
|
||||
}
|
||||
function doUpdate() {
|
||||
var id_list_string = id_list.join(',');
|
||||
var url = "{% url 'assets:asset-bulk-update' %}?assets_id=" + id_list_string;
|
||||
location.href = url
|
||||
}
|
||||
switch(action) {
|
||||
case 'deactive':
|
||||
doDeactive();
|
||||
break;
|
||||
case 'delete':
|
||||
doDelete();
|
||||
break;
|
||||
case 'update':
|
||||
doUpdate();
|
||||
break;
|
||||
case 'active':
|
||||
doActive();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -20,14 +20,6 @@
|
|||
<li class="active">
|
||||
<a href="{% url 'assets:admin-user-assets' pk=admin_user.pk %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Assets list' %} </a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-default" href="{% url 'assets:admin-user-update' pk=admin_user.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-danger btn-delete-admin-user">
|
||||
<i class="fa fa-trash-o"></i>{% trans 'Delete' %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
|
@ -127,14 +119,6 @@ function initTable() {
|
|||
$(document).ready(function () {
|
||||
initTable();
|
||||
})
|
||||
.on('click', '.btn-delete-admin-user', function () {
|
||||
var $this = $(this);
|
||||
var name = "{{ admin_user.name }}";
|
||||
var uid = "{{ admin_user.id }}";
|
||||
var the_url = '{% url "api-assets:admin-user-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
|
||||
var redirect_url = "{% url 'assets:admin-user-list' %}";
|
||||
objectDelete($this, name, the_url, redirect_url);
|
||||
})
|
||||
.on('click', '.btn-test-connective', function () {
|
||||
var the_url = "{% url 'api-assets:admin-user-connective' pk=admin_user.id %}";
|
||||
var error = function (data) {
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-7" style="padding-left: 0;">
|
||||
<div class="col-sm-8" style="padding-left: 0;">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span class="label"><b>{{ admin_user.name }}</b></span>
|
||||
|
@ -77,11 +77,10 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||
|
||||
<div class="panel panel-info">
|
||||
<div class="col-sm-4" style="padding-left: 0;padding-right: 0">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Using this as cluster admin user' %}
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Replace assets admin user with this' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table group_edit" id="table-clusters">
|
||||
|
@ -89,25 +88,19 @@
|
|||
<form>
|
||||
<tr>
|
||||
<td colspan="2" class="no-borders">
|
||||
<select data-placeholder="{% trans 'Select cluster' %}" id="cluster_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for cluster in cluster_remain %}
|
||||
<option value="{{ cluster.id }}" id="opt_{{ cluster.id }}" >{{ cluster.name }}</option>
|
||||
<select data-placeholder="{% trans 'Nodes' %}" id="nodes_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for node in nodes %}
|
||||
<option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node.value }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="no-borders">
|
||||
<button type="button" class="btn btn-info btn-sm" id="btn-add-cluster">{% trans 'Confirm' %}</button>
|
||||
<button type="button" class="btn btn-primary btn-sm" id="btn-change-admin-user">{% trans 'Confirm' %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
|
||||
{% for cluster in admin_user.cluster_set.all %}
|
||||
<tr>
|
||||
<td ><b class="bdg_cluster" data-gid={{ cluster.id }}>{{ cluster.name }}</b></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -123,29 +116,20 @@
|
|||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
function bindToCluster(clusters) {
|
||||
var the_url = "{% url 'api-assets:admin-user-add-clusters' pk=admin_user.id %}";
|
||||
function replaceNodeAssetsAdminUser(nodes) {
|
||||
var the_url = "{% url 'api-assets:replace-nodes-admin-user' pk=admin_user.id %}";
|
||||
var body = {
|
||||
clusters: clusters
|
||||
nodes: nodes
|
||||
};
|
||||
var success = function(data) {
|
||||
// remove all the selected groups from select > option and rendered ul element;
|
||||
$('.select2-selection__rendered').empty();
|
||||
$('#cluster_selected').val('');
|
||||
$.map(jumpserver.cluster_selected, function(cluster_name, index) {
|
||||
$('#opt_' + index).remove();
|
||||
// change tr html of user groups.
|
||||
$('#table-clusters tbody').append(
|
||||
'<tr>' +
|
||||
'<td><b class="bdg_cluster" data-gid="' + index + '">' + cluster_name + '</b></td>' +
|
||||
'</tr>'
|
||||
)
|
||||
});
|
||||
$.map(jumpserver.cluster_selected, function(value, index) {
|
||||
$('#nodes_selected').val('');
|
||||
$.map(jumpserver.nodes_selected, function(value, index) {
|
||||
$('#opt_' + index).remove();
|
||||
});
|
||||
// clear jumpserver.groups_selected
|
||||
jumpserver.cluster_selected = {};
|
||||
jumpserver.nodes_selected = {};
|
||||
};
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
|
@ -154,15 +138,15 @@ function bindToCluster(clusters) {
|
|||
});
|
||||
}
|
||||
|
||||
jumpserver.cluster_selected = {};
|
||||
jumpserver.nodes_selected = {};
|
||||
$(document).ready(function () {
|
||||
$('.select2').select2()
|
||||
.on('select2:select', function(evt) {
|
||||
var data = evt.params.data;
|
||||
jumpserver.cluster_selected[data.id] = data.text;
|
||||
jumpserver.nodes_selected[data.id] = data.text;
|
||||
}).on('select2:unselect', function(evt) {
|
||||
var data = evt.params.data;
|
||||
delete jumpserver.cluster_selected[data.id]
|
||||
delete jumpserver.nodes_selected[data.id]
|
||||
});
|
||||
})
|
||||
.on('click', '.btn-delete-admin-user', function () {
|
||||
|
@ -173,15 +157,15 @@ $(document).ready(function () {
|
|||
var redirect_url = "{% url 'assets:admin-user-list' %}";
|
||||
objectDelete($this, name, the_url, redirect_url);
|
||||
})
|
||||
.on('click', '#btn-add-cluster', function () {
|
||||
if (Object.keys(jumpserver.cluster_selected).length === 0) {
|
||||
.on('click', '#btn-change-admin-user', function () {
|
||||
if (Object.keys(jumpserver.nodes_selected).length === 0) {
|
||||
return false;
|
||||
}
|
||||
var clusters = [];
|
||||
$.map(jumpserver.cluster_selected, function(value, index) {
|
||||
clusters.push(index);
|
||||
var nodes = [];
|
||||
$.map(jumpserver.nodes_selected, function(value, index) {
|
||||
nodes.push(index);
|
||||
});
|
||||
bindToCluster(clusters)
|
||||
replaceNodeAssetsAdminUser(nodes);
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -73,10 +73,6 @@
|
|||
<td>{% trans 'Admin user' %}:</td>
|
||||
<td><b>{{ asset.admin_user }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Cluster' %}:</td>
|
||||
<td><b>{{ asset.cluster.name }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Vendor' %}:</td>
|
||||
<td><b>{{ asset.vendor|default:"" }}</b></td>
|
||||
|
@ -182,7 +178,7 @@
|
|||
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Asset groups' %}
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Nodes' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table group_edit" id="add-asset2group">
|
||||
|
@ -190,25 +186,25 @@
|
|||
<form>
|
||||
<tr>
|
||||
<td colspan="2" class="no-borders">
|
||||
<select data-placeholder="{% trans 'Join asset groups' %}" id="groups_selected" class="select2 groups" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for asset_group in asset_groups_remain %}
|
||||
<option value="{{ asset_group.id }}" id="opt_{{ asset_group.id }}" >{{ asset_group.name }}</option>
|
||||
<select data-placeholder="{% trans 'Nodes' %}" id="groups_selected" class="select2 groups" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for node in nodes_remain %}
|
||||
<option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" class="no-borders">
|
||||
<button type="button" class="btn btn-info btn-sm" id="btn-add-user-group">{% trans 'Confirm' %}</button>
|
||||
<button type="button" class="btn btn-info btn-sm" id="btn-update-nodes">{% trans 'Confirm' %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
|
||||
{% for asset_group in asset_groups %}
|
||||
{% for node in asset.nodes.all %}
|
||||
<tr>
|
||||
<td ><b class="bdg_group" data-gid={{ asset_group.id }}>{{ asset_group.name }}</b></td>
|
||||
<td ><b class="bdg_node" data-gid={{ node.id }}>{{ node.name }}</b></td>
|
||||
<td>
|
||||
<button class="btn btn-danger pull-right btn-xs btn-leave-group" type="button"><i class="fa fa-minus"></i></button>
|
||||
<button class="btn btn-danger pull-right btn-xs btn-leave-node" type="button"><i class="fa fa-minus"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -239,28 +235,28 @@
|
|||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
jumpserver.groups_selected = {};
|
||||
function updateAssetGroups(groups) {
|
||||
jumpserver.nodes_selected = {};
|
||||
function updateAssetNodes(nodes) {
|
||||
var the_url = "{% url 'api-assets:asset-detail' pk=asset.id %}";
|
||||
var body = {
|
||||
groups: Object.assign([], groups)
|
||||
nodes: Object.assign([], nodes)
|
||||
};
|
||||
var success = function(data) {
|
||||
// remove all the selected groups from select > option and rendered ul element;
|
||||
$('.select2-selection__rendered').empty();
|
||||
$('#groups_selected').val('');
|
||||
$.map(jumpserver.groups_selected, function(group_name, index) {
|
||||
$.map(jumpserver.nodes_selected, function(group_name, index) {
|
||||
$('#opt_' + index).remove();
|
||||
// change tr html of user groups.
|
||||
$('#add-asset2group tbody').append(
|
||||
'<tr>' +
|
||||
'<td><b class="bdg_group" data-gid="' + index + '">' + group_name + '</b></td>' +
|
||||
'<td><button class="btn btn-danger btn-xs pull-right btn-leave-group" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||
'<td><b class="bdg_node" data-gid="' + index + '">' + group_name + '</b></td>' +
|
||||
'<td><button class="btn btn-danger btn-xs pull-right btn-leave-node" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||
'</tr>'
|
||||
)
|
||||
});
|
||||
// clear jumpserver.groups_selected
|
||||
jumpserver.groups_selected = {};
|
||||
jumpserver.nodes_selected = {};
|
||||
};
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
|
@ -289,10 +285,10 @@ function refreshAssetHardware() {
|
|||
$(document).ready(function () {
|
||||
$('.select2.groups').select2().on('select2:select', function(evt) {
|
||||
var data = evt.params.data;
|
||||
jumpserver.groups_selected[data.id] = data.text;
|
||||
jumpserver.nodes_selected[data.id] = data.text;
|
||||
}).on('select2:unselect', function(evt) {
|
||||
var data = evt.params.data;
|
||||
delete jumpserver.groups_selected[data.id]
|
||||
delete jumpserver.nodes_selected[data.id]
|
||||
});
|
||||
}).on('click', '#is_active', function () {
|
||||
var the_url = '{% url "api-assets:asset-detail" pk=asset.id %}';
|
||||
|
@ -307,37 +303,37 @@ $(document).ready(function () {
|
|||
body: JSON.stringify(body),
|
||||
success_message: success
|
||||
});
|
||||
if (status == "False") {
|
||||
if (status === "False") {
|
||||
$(".ibox-content > table > tbody > tr:nth-child(13) > td:last >b").html('True');
|
||||
}else{
|
||||
$(".ibox-content > table > tbody > tr:nth-child(13) > td:last >b").html('False');
|
||||
}
|
||||
}).on('click', '#btn-add-user-group', function () {
|
||||
if (Object.keys(jumpserver.groups_selected).length === 0) {
|
||||
}).on('click', '#btn-update-nodes', function () {
|
||||
if (Object.keys(jumpserver.nodes_selected).length === 0) {
|
||||
return false;
|
||||
}
|
||||
var groups = $('.bdg_group').map(function() {
|
||||
var nodes = $('.bdg_node').map(function() {
|
||||
return $(this).data('gid');
|
||||
}).get();
|
||||
$.map(jumpserver.groups_selected, function(value, index) {
|
||||
groups.push(index);
|
||||
$.map(jumpserver.nodes_selected, function(value, index) {
|
||||
nodes.push(index);
|
||||
$('#opt_' + index).remove();
|
||||
});
|
||||
updateAssetGroups(groups)
|
||||
}).on('click', '.btn-leave-group', function() {
|
||||
updateAssetNodes(nodes)
|
||||
}).on('click', '.btn-leave-node', function() {
|
||||
var $this = $(this);
|
||||
var $tr = $this.closest('tr');
|
||||
var $badge = $tr.find('.bdg_group');
|
||||
var $badge = $tr.find('.bdg_node');
|
||||
var gid = $badge.data('gid');
|
||||
var group_name = $badge.html() || $badge.text();
|
||||
$('#groups_selected').append(
|
||||
'<option value="' + gid + '" id="opt_' + gid + '">' + group_name + '</option>'
|
||||
);
|
||||
$tr.remove();
|
||||
var groups = $('.bdg_group').map(function () {
|
||||
var groups = $('.bdg_node').map(function () {
|
||||
return $(this).data('gid');
|
||||
}).get();
|
||||
updateAssetGroups(groups)
|
||||
updateAssetNodes(groups)
|
||||
}).on('click', '.btn-delete-asset', function () {
|
||||
var $this = $(this);
|
||||
var name = "{{ asset.hostname }}";
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
{% extends '_base_create_update.html' %}
|
||||
{% load static %}
|
||||
{% load bootstrap3 %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block form %}
|
||||
<form id="groupForm" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_field form.name layout="horizontal" %}
|
||||
{% bootstrap_field form.assets layout="horizontal" %}
|
||||
{% bootstrap_field form.comment layout="horizontal" %}
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-4 col-sm-offset-2">
|
||||
<button class="btn btn-default" type="reset"> {% trans 'Reset' %}</button>
|
||||
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block custom_foot_js %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function () {
|
||||
$('.select2').select2({
|
||||
closeOnSelect: false
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,244 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Group assets' %} </a></li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-default" href="{% url 'assets:asset-group-update' pk=asset_group.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-danger btn-del">
|
||||
<i class="fa fa-trash-o"></i>{% trans 'Delete' %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-8" style="padding-left: 0">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span style="float: left">{% trans 'Asset list of ' %} <b>{{ asset_group.name }} </b><span class="badge"> {{ asset_group.assets.all.count }}</span></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">
|
||||
<table class="table table-hover " id="asset_list_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans 'Hostname' %}</th>
|
||||
<th>{% trans 'IP' %}</th>
|
||||
<th>{% trans 'Port' %}</th>
|
||||
<th>{% trans 'Alive' %}</th>
|
||||
<th>{% trans 'Action' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4" style="padding-left: 0;padding-right: 0">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Add assets to this group' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="2">
|
||||
<select data-placeholder="{% trans 'Select assets' %}" class="select2 asset-select" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for asset in assets_remain %}
|
||||
<option value="{{ asset.id }}"> {{ asset.hostname }} </option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="2">
|
||||
<button type="button" class="btn btn-primary btn-sm btn-add-asset">{% trans 'Add' %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
jumpserver.assets_selected = {};
|
||||
function addAssets(assets) {
|
||||
var the_url = "{% url 'api-assets:group-add-assets' pk=asset_group.id %}";
|
||||
var body = {
|
||||
assets: assets
|
||||
};
|
||||
|
||||
var $data_table = $("#asset_list_table").DataTable();
|
||||
var success = function(data) {
|
||||
$('.select2-selection__rendered').empty();
|
||||
$data_table.ajax.reload();
|
||||
jumpserver.groups_selected = {};
|
||||
};
|
||||
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
body: JSON.stringify(body),
|
||||
method: 'PUT',
|
||||
success: success
|
||||
});
|
||||
}
|
||||
|
||||
function leaveGroup(obj, name, url, data) {
|
||||
var body = data;
|
||||
var success = function() {
|
||||
$(obj).parent().parent().remove();
|
||||
};
|
||||
var fail = function() {
|
||||
console.log("Remove failed")
|
||||
};
|
||||
APIUpdateAttr({
|
||||
url: url,
|
||||
body: JSON.stringify(body),
|
||||
method: 'PATCH',
|
||||
success: success,
|
||||
error: fail
|
||||
});
|
||||
}
|
||||
|
||||
Array.prototype.remove = function(val) {
|
||||
var index = this.indexOf(val);
|
||||
if (index > -1) {
|
||||
this.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
Array.prototype.unique = function(){
|
||||
var res = [];
|
||||
var json = {};
|
||||
for(var i = 0; i < this.length; i++){
|
||||
if(!json[this[i]]){
|
||||
res.push(this[i]);
|
||||
json[this[i]] = 1;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
function initTable() {
|
||||
var options = {
|
||||
ele: $('#asset_list_table'),
|
||||
buttons: [],
|
||||
order: [],
|
||||
columnDefs: [
|
||||
{targets: 0, createdCell: function (td, cellData, rowData) {
|
||||
var detail_btn = '<a href="{% url "assets:asset-detail" pk=DEFAULT_PK %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||
}},
|
||||
{targets: 3, createdCell: function (td, cellData) {
|
||||
if (!cellData) {
|
||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||
} else {
|
||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
||||
}
|
||||
}},
|
||||
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = '<a href="{% url "assets:asset-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', rowData.id);
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-leave-group" data-aid="{{ DEFAULT_PK }}">{% trans "Remove" %}</a>'.replace('{{ DEFAULT_PK }}', rowData.id);
|
||||
$(td).html(update_btn + del_btn)
|
||||
}}
|
||||
],
|
||||
ajax_url: '{% url "api-assets:asset-list" %}?asset_group_id={{ asset_group.id }}',
|
||||
columns: [
|
||||
{data: "hostname" }, {data: "ip" }, {data: "port" },
|
||||
{data: "is_connective" }, {data: "id"}],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initServerSideDataTable(options);
|
||||
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$('.select2').select2();
|
||||
|
||||
$('.select2.asset-select').select2()
|
||||
.on('select2:select', function(evt) {
|
||||
var data = evt.params.data;
|
||||
jumpserver.assets_selected[data.id] = data.text;
|
||||
})
|
||||
.on('select2:unselect', function(evt) {
|
||||
var data = evt.params.data;
|
||||
delete jumpserver.assets_selected[data.id]
|
||||
});
|
||||
|
||||
initTable();
|
||||
|
||||
})
|
||||
|
||||
.on('click', ".btn-add-asset", function () {
|
||||
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
||||
return false;
|
||||
}
|
||||
var assets_id = [];
|
||||
$.map(jumpserver.assets_selected, function(value, index) {
|
||||
assets_id.push(index);
|
||||
});
|
||||
|
||||
addAssets(assets_id);
|
||||
})
|
||||
|
||||
.on('click', '.btn-leave-group', function () {
|
||||
var $this = $(this);
|
||||
var the_url = "{% url 'api-assets:group-update-assets' pk=asset_group.id %}";
|
||||
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
|
||||
var assets = [];
|
||||
$('#asset_list_table > tbody > tr').map(function () {
|
||||
assets.push($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid"))
|
||||
});
|
||||
var delete_asset_id = $(this).data('aid');
|
||||
assets.remove(delete_asset_id);
|
||||
var data = {"assets": assets};
|
||||
leaveGroup($this, name, the_url, data);
|
||||
}).on('click', '.btn-del', function () {
|
||||
var $this = $(this);
|
||||
var name = "{{ asset_group.name}}";
|
||||
var uid = "{{ asset_group.id }}";
|
||||
var the_url = '{% url "api-assets:asset-group-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
|
||||
var redirect_url = "{% url 'assets:asset-group-list' %}";
|
||||
objectDelete($this, name, the_url, redirect_url);
|
||||
})
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,168 +0,0 @@
|
|||
{% extends '_base_list.html' %}
|
||||
{% load i18n static %}
|
||||
{% block table_search %}
|
||||
{% endblock %}
|
||||
{% block table_container %}
|
||||
<div class="uc pull-left m-r-5">
|
||||
<a href="{% url "assets:asset-group-create" %}" class="btn btn-sm btn-primary"> {% trans "Create asset group" %} </a>
|
||||
</div>
|
||||
<table class="table table-striped table-bordered table-hover " id="asset_groups_list_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">
|
||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
||||
</th>
|
||||
<th class="text-center">{% trans 'Name' %}</th>
|
||||
<th class="text-center">{% trans 'Asset' %}</th>
|
||||
<th class="text-center">{% trans 'Comment' %}</th>
|
||||
<th class="text-center">{% trans 'Action' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
{% include 'assets/_asset_group_bulk_update_modal.html' %}
|
||||
{% endblock %}
|
||||
{% block content_bottom_left %}{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var options = {
|
||||
ele: $('#asset_groups_list_table'),
|
||||
columnDefs: [
|
||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||
var detail_btn = '<a href="{% url "assets:asset-group-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||
}},
|
||||
{targets: 2, createdCell: function (td, cellData, rowData) {
|
||||
var html = createPopover(cellData);
|
||||
$(td).html(html);
|
||||
}},
|
||||
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = '<a href="{% url "assets:asset-group-update" pk=DEFAULT_PK %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_group_delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
|
||||
$(td).html(update_btn + del_btn)
|
||||
}}],
|
||||
ajax_url: '{% url "api-assets:asset-group-list" %}',
|
||||
columns: [{data: "id"}, {data: "name" }, {data: "assets_display" }, {data: "comment" }, {data: "id"}],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
})
|
||||
|
||||
.on('click', '.btn_asset_group_delete', function () {
|
||||
var $this = $(this);
|
||||
var $data_table = $('#asset_groups_list_table').DataTable();
|
||||
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||
var uid = $this.data('uid');
|
||||
var the_url = '{% url "api-assets:asset-group-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
|
||||
objectDelete($this, name, the_url);
|
||||
setTimeout( function () {
|
||||
$data_table.ajax.reload();
|
||||
}, 3000);
|
||||
})
|
||||
|
||||
.on('click', '#btn_bulk_update', function () {
|
||||
var action = $('#slct_bulk_update').val();
|
||||
var $data_table = $('#asset_groups_list_table').DataTable();
|
||||
var id_list = [];
|
||||
var plain_id_list = [];
|
||||
$data_table.rows({selected: true}).every(function(){
|
||||
id_list.push({id: this.data().id});
|
||||
plain_id_list.push(this.data().id);
|
||||
});
|
||||
if (id_list === []) {
|
||||
return false;
|
||||
}
|
||||
var the_url = '{% url "api-assets:asset-group-list" %}';
|
||||
function doDelete() {
|
||||
swal({
|
||||
title: "{% trans 'Are you sure?' %}",
|
||||
text: "{% trans 'This will delete the selected groups !!!' %}",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: "{% trans 'Confirm' %}",
|
||||
closeOnConfirm: false
|
||||
}, function() {
|
||||
var success = function() {
|
||||
var msg = "{% trans 'Group deleted' %}";
|
||||
swal("{% trans 'Group Delete' %}", msg, "success");
|
||||
$('#asset_groups_list_table').DataTable().ajax.reload();
|
||||
};
|
||||
var fail = function() {
|
||||
var msg = "{% trans 'Group deleting failed.' %}";
|
||||
swal("{% trans 'Group Delete' %}", msg, "error");
|
||||
};
|
||||
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
|
||||
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
|
||||
$data_table.ajax.reload();
|
||||
jumpserver.checked = false;
|
||||
});
|
||||
}
|
||||
function doUpdate() {
|
||||
$('#asset_group_bulk_update_modal').modal('show');
|
||||
}
|
||||
switch(action) {
|
||||
case 'delete':
|
||||
doDelete();
|
||||
break;
|
||||
case 'update':
|
||||
doUpdate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
})
|
||||
|
||||
.on('click', '#btn_asset_group_bulk_update', function () {
|
||||
var json_data = $("#fm_asset_group_bulk_update").serializeObject();
|
||||
var body = {};
|
||||
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
|
||||
if (json_data.type != '') {
|
||||
body.type = json_data.type;
|
||||
}
|
||||
|
||||
if (json_data.assets != undefined) {
|
||||
body.assets = json_data.assets;
|
||||
}
|
||||
if (typeof body.assets === 'string') {
|
||||
body.assets = [parseInt(body.assets)]
|
||||
} else if(typeof body.assets === 'array') {
|
||||
var new_assets = body.assets.map(Number);
|
||||
body.assets = new_assets;
|
||||
}
|
||||
|
||||
if (json_data.system_users != undefined) {
|
||||
body.system_users = json_data.system_users;
|
||||
}
|
||||
if (typeof body.system_users === 'string') {
|
||||
body.system_users = [parseInt(body.system_users)];
|
||||
} else if (typeof body.system_users === 'array') {
|
||||
var new_system_users = body.system_users.map(Number);
|
||||
body.system_users = new_system_users;
|
||||
}
|
||||
|
||||
var post_list = [];
|
||||
var $data_table = $('#asset_groups_list_table').DataTable()
|
||||
$data_table.rows({selected: true}).every(function(){
|
||||
var content = Object.assign({id: this.data().id}, body);
|
||||
post_list.push(content);
|
||||
});
|
||||
if (post_list === []) {
|
||||
return false
|
||||
}
|
||||
var the_url = '{% url "api-assets:asset-group-list" %}';
|
||||
var success = function() {
|
||||
var msg = "{% trans 'The selected asset groups has been updated successfully.' %}";
|
||||
swal("{% trans 'AssetGroup Updated' %}", msg, "success");
|
||||
$('#asset_groups_list_table').DataTable().ajax.reload();
|
||||
jumpserver.checked = false;
|
||||
};
|
||||
{# console.log(JSON.stringify(post_list));#}
|
||||
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});
|
||||
$('#asset_group_bulk_update_modal').modal('hide');
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
@ -325,9 +325,9 @@ function initTree() {
|
|||
$.get("{% url 'api-assets:node-list' %}", function(data, status){
|
||||
$.each(data, function (index, value) {
|
||||
value["pId"] = value["parent"];
|
||||
if (value["key"] === "0") {
|
||||
value["open"] = true;
|
||||
}
|
||||
{#if (value["key"] === "0") {#}
|
||||
value["open"] = true;
|
||||
{# }#}
|
||||
value["name"] = value["value"]
|
||||
});
|
||||
zNodes = data;
|
||||
|
|
|
@ -1,215 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||
<style type="text/css">
|
||||
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li>
|
||||
<a href="{% url 'assets:cluster-detail' pk=cluster.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
|
||||
</li>
|
||||
<li class="active"><a href="{% url 'assets:cluster-assets' pk=cluster.id %}" class="text-center">
|
||||
<i class="fa fa-bar-chart-o"></i> {% trans 'Cluster assets' %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-8" style="padding-left: 0;">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span style="float: left">{% trans 'Cluster assets' %} <b>{{ cluster.name }} </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">
|
||||
<table class="table table-hover " id="cluster_assets_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans 'Hostname' %}</th>
|
||||
<th>{% trans 'IP' %}</th>
|
||||
<th>{% trans 'Port' %}</th>
|
||||
<th>{% trans 'Alive' %}</th>
|
||||
<th>{% trans 'Action' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4" style="padding-left: 0;padding-right: 0">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Quick update' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr class="no-borders-tr">
|
||||
<td width="50%">{% trans 'Test assets connective' %}:</td>
|
||||
<td>
|
||||
<span style="float: right">
|
||||
<button type="button" class="btn btn-primary btn-xs" id="btn-test-assets" style="width: 54px">{% trans 'Run' %}</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Add assets to' %} {{ cluster.name }}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="2">
|
||||
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for asset in assets_remain %}
|
||||
<option value="{{ asset.id }}" id="opt_{{ asset.id }}">{{ asset.hostname}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="2">
|
||||
<button type="button" class="btn btn-info btn-sm btn-add-assets">{% trans 'Confirm' %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
||||
<script>
|
||||
|
||||
jumpserver.assets_selected = {};
|
||||
|
||||
Array.prototype.remove = function(val) {
|
||||
var index = this.indexOf(val);
|
||||
if (index > -1) {
|
||||
this.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
function addAssets(assets) {
|
||||
var the_url = "{% url 'api-assets:cluster-add-assets' pk=cluster.id %}";
|
||||
var body = {
|
||||
assets: assets
|
||||
};
|
||||
var $data_table = $("#cluster_assets_table").DataTable();
|
||||
var success = function(data) {
|
||||
$('.select2-selection__rendered').empty();
|
||||
$data_table.ajax.reload();
|
||||
jumpserver.groups_selected = {};
|
||||
};
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
body: JSON.stringify(body),
|
||||
method: 'PUT',
|
||||
success: success
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function initTable() {
|
||||
var options = {
|
||||
ele: $('#cluster_assets_table'),
|
||||
buttons: [],
|
||||
order: [],
|
||||
columnDefs: [
|
||||
{targets: 0, createdCell: function (td, cellData, rowData) {
|
||||
var detail_btn = '<a href="{% url "assets:asset-detail" pk=DEFAULT_PK %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||
}},
|
||||
{targets: 3, createdCell: function (td, cellData) {
|
||||
if (!cellData) {
|
||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||
} else {
|
||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
||||
}
|
||||
}},
|
||||
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = '<a href="{% url "assets:asset-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', rowData.id);
|
||||
$(td).html(update_btn)
|
||||
}}
|
||||
],
|
||||
ajax_url: '{% url "api-assets:asset-list" %}?cluster_id={{ cluster.id }}',
|
||||
columns: [
|
||||
{data: "hostname" }, {data: "ip" }, {data: "port" },
|
||||
{data: "is_connective" }, {data: "id"}],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initServerSideDataTable(options);
|
||||
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
$('.select2').select2()
|
||||
.on("select2:select", function (evt) {
|
||||
var data = evt.params.data;
|
||||
jumpserver.assets_selected[data.id] = data.text;
|
||||
})
|
||||
.on('select2:unselect', function(evt) {
|
||||
var data = evt.params.data;
|
||||
delete jumpserver.assets_selected[data.id];
|
||||
});
|
||||
initTable();
|
||||
})
|
||||
.on('click', '.btn-add-assets', function () {
|
||||
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
||||
return false;
|
||||
}
|
||||
var assets_id = [];
|
||||
$.map(jumpserver.assets_selected, function(value, index) {
|
||||
assets_id.push(index);
|
||||
});
|
||||
|
||||
addAssets(assets_id);
|
||||
})
|
||||
.on('click', '#btn-test-assets', function () {
|
||||
var the_url = "{% url 'api-assets:cluster-test-connective' pk=cluster.id %}";
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
method: 'GET',
|
||||
success_message: "{% trans 'Task has been send, seen left assets status' %}"
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,76 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
{% load bootstrap3 %}
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-10">
|
||||
<div class="ibox float-e-margins">
|
||||
<div id="ibox-content" class="ibox-title">
|
||||
<h5> {{ action }}</h5>
|
||||
<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>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ibox-content">
|
||||
<div class="panel blank-panel">
|
||||
<div class="panel-body">
|
||||
<div class="tab-content">
|
||||
<form id="ClusterForm" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
<h3 class="widget-head-color-box">{% trans 'Basic' %}</h3>
|
||||
{% bootstrap_field form.name layout="horizontal" %}
|
||||
{% bootstrap_field form.address layout="horizontal" %}
|
||||
{% bootstrap_field form.contact layout="horizontal" %}
|
||||
{% bootstrap_field form.phone layout="horizontal" %}
|
||||
|
||||
<h3 class="widget-head-color-box">{% trans 'Setting' %}</h3>
|
||||
{% bootstrap_field form.admin_user layout="horizontal" %}
|
||||
{% bootstrap_field form.system_users layout="horizontal" %}
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
<h3 class="widget-head-color-box">{% trans 'Other' %}</h3>
|
||||
{% bootstrap_field form.operator layout="horizontal" %}
|
||||
{% bootstrap_field form.intranet layout="horizontal" %}
|
||||
{% bootstrap_field form.extranet layout="horizontal" %}
|
||||
|
||||
<div class="hr-line-dashed"></div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-4 col-sm-offset-2">
|
||||
<button class="btn btn-default" type="reset"> {% trans 'Reset' %}</button>
|
||||
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('.select2').select2();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,164 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a href="{% url 'assets:cluster-detail' pk=cluster.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'assets:cluster-assets' pk=cluster.id %}" class="text-center">
|
||||
<i class="fa fa-bar-chart-o"></i> {% trans 'Cluster assets' %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-default" href="{% url 'assets:cluster-update' pk=cluster.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-danger btn-delete-cluster">
|
||||
<i class="fa fa-trash-o"></i>{% trans 'Delete' %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-8" style="padding-left: 0;">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span class="label"><b>{{ cluster.name }}</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">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr class="no-borders-tr">
|
||||
<td width="20%">{% trans 'Name' %}:</td>
|
||||
<td><b>{{ cluster.name }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Bandwidth' %}:</td>
|
||||
<td><b>{{ cluster.bandwidth }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Contact' %}:</td>
|
||||
<td><b>{{ cluster.contact }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Phone' %}:</td>
|
||||
<td><b>{{ cluster.phone }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Address' %}:</td>
|
||||
<td><b>{{ cluster.address }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Intranet' %}:</td>
|
||||
<td><b>{{ cluster.Intranet }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Extranet' %}:</td>
|
||||
<td><b>{{ cluster.extranet }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Operator' %}:</td>
|
||||
<td><b>{{ cluster.operator }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Date created' %}:</td>
|
||||
<td><b>{{ system_user.date_created }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Created by' %}:</td>
|
||||
<td><b>{{ asset_group.created_by }}</b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{% trans 'Comment' %}:</td>
|
||||
<td><b>{{ system_user.comment }}</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{# <div class="col-sm-4" style="padding-left: 0;padding-right: 0">#}
|
||||
{# <div class="panel panel-primary">#}
|
||||
{# <div class="panel-heading">#}
|
||||
{# <i class="fa fa-info-circle"></i> {% trans 'Update admin user' %}#}
|
||||
{# </div>#}
|
||||
{# <div class="panel-body">#}
|
||||
{# <table class="table cluster_edit" id="add-asset2group">#}
|
||||
{# <tbody>#}
|
||||
{# <form>#}
|
||||
{# <tr>#}
|
||||
{# <td colspan="2" class="no-borders">#}
|
||||
{# <select data-placeholder="{% trans 'Select admin user' %}" id="cluster_selected" class="select2" style="width: 100%" tabindex="4">#}
|
||||
{# {% for admin_user in admin_user_list %}#}
|
||||
{# <option value="{{ admin_user.id }}" id="opt_{{ admin_user.id }}" {% if admin_user.id == cluster.admin_user.id %} selected {% endif %} >{{ admin_user.name }}</option>#}
|
||||
{# {% endfor %}#}
|
||||
{# </select>#}
|
||||
{# </td>#}
|
||||
{# </tr>#}
|
||||
{# <tr>#}
|
||||
{# <td colspan="2" class="no-borders">#}
|
||||
{# <button type="button" class="btn btn-primary btn-sm" id="btn-add-to-cluster">{% trans 'Confirm' %}</button>#}
|
||||
{# </td>#}
|
||||
{# </tr>#}
|
||||
{# </form>#}
|
||||
{##}
|
||||
{# {% for cluster in system_user.cluster.all %}#}
|
||||
{# <tr>#}
|
||||
{# <td ><b class="bdg_cluster" data-gid={{ cluster.id }}>{{ cluster.name }}</b></td>#}
|
||||
{# <td>#}
|
||||
{# <button class="btn btn-danger pull-right btn-xs btn-remove-from-cluster" type="button"><i class="fa fa-minus"></i></button>#}
|
||||
{# </td>#}
|
||||
{# </tr>#}
|
||||
{# {% endfor %}#}
|
||||
{# </tbody>#}
|
||||
{# </table>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
{# </div>#}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
$('.select2').select2();
|
||||
})
|
||||
.on('click', '.btn-delete-cluster', function () {
|
||||
var name = "{{ cluster.name }}";
|
||||
var id = "{{ cluster.id }}";
|
||||
var the_url = '{% url "api-assets:cluster-detail" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", id);
|
||||
var redirect_url = "{% url 'assets:cluster-list' %}";
|
||||
objectDelete(this, name, the_url, redirect_url);
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,119 +0,0 @@
|
|||
{% extends '_base_list.html' %}
|
||||
{% load i18n static %}
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block table_search %}{% endblock %}
|
||||
{% block table_container %}
|
||||
<div class="uc pull-left m-r-5">
|
||||
<a href="{% url "assets:cluster-create" %}" class="btn btn-sm btn-primary"> {% trans "Create cluster" %} </a>
|
||||
</div>
|
||||
<table class="table table-striped table-bordered table-hover " id="cluster_list_table" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">
|
||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
||||
</th>
|
||||
<th class="text-center"><a href="{% url 'assets:cluster-list' %}?sort=name">{% trans 'Name' %}</a></th>
|
||||
<th class="text-center">{% trans 'Admin user' %}</th>
|
||||
<th class="text-center">{% trans 'Asset num' %}</th>
|
||||
<th class="text-center">{% trans 'System users' %}</th>
|
||||
<th class="text-center">{% trans 'Action' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
{% block content_bottom_left %}{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var options = {
|
||||
ele: $('#cluster_list_table'),
|
||||
columnDefs: [
|
||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||
var detail_btn = '<a href="{% url "assets:cluster-detail" pk=DEFAULT_PK %}">' + cellData + '</a>';
|
||||
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||
}},
|
||||
|
||||
{targets: 5, createdCell: function (td, cellData, rowData) {
|
||||
var update_btn = '<a href="{% url "assets:cluster-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
|
||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_cluster_delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);
|
||||
$(td).html(update_btn + del_btn)
|
||||
}}],
|
||||
ajax_url: '{% url "api-assets:cluster-list" %}',
|
||||
columns: [
|
||||
{data: "id"}, {data: "name" }, {data: "admin_user_name"}, {data: "assets_amount" },
|
||||
{data: "system_users" }, {data: "id" }
|
||||
],
|
||||
op_html: $('#actions').html()
|
||||
};
|
||||
jumpserver.initDataTable(options);
|
||||
})
|
||||
|
||||
.on('click', '.btn_cluster_delete', function () {
|
||||
var $this = $(this);
|
||||
var $data_table = $('#cluster_list_table').DataTable();
|
||||
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||
var uid = $this.data('uid');
|
||||
var the_url = '{% url "api-assets:cluster-detail" pk=DEFAULT_PK %}'.replace('{{ DEFAULT_PK }}', uid);
|
||||
objectDelete($this, name, the_url);
|
||||
setTimeout( function () {
|
||||
$data_table.ajax.reload();
|
||||
}, 3000);
|
||||
})
|
||||
|
||||
.on('click', '#btn_bulk_update', function () {
|
||||
var action = $('#slct_bulk_update').val();
|
||||
var $data_table = $('#cluster_list_table').DataTable();
|
||||
var id_list = [];
|
||||
var plain_id_list = [];
|
||||
$data_table.rows({selected: true}).every(function(){
|
||||
id_list.push({id: this.data().id});
|
||||
plain_id_list.push(this.data().id);
|
||||
});
|
||||
if (id_list === []) {
|
||||
return false;
|
||||
}
|
||||
var the_url = "{% url 'api-assets:cluster-list' %}";
|
||||
function doDelete() {
|
||||
swal({
|
||||
title: "{% trans 'Are you sure?' %}",
|
||||
text: "{% trans 'This will delete the selected cluster' %}",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: "{% trans 'Confirm' %}",
|
||||
closeOnConfirm: false
|
||||
}, function() {
|
||||
var success = function() {
|
||||
var msg = "{% trans 'Cluster Deleted.' %}";
|
||||
swal("{% trans 'Cluster delete' %}", msg, "success");
|
||||
$('#cluster_list_table').DataTable().ajax.reload();
|
||||
};
|
||||
var fail = function() {
|
||||
var msg = "{% trans 'Cluster deleting failed.' %}";
|
||||
swal("{% trans 'Cluster delete' %}", msg, "error");
|
||||
};
|
||||
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
|
||||
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
|
||||
$data_table.ajax.reload();
|
||||
jumpserver.checked = false;
|
||||
});
|
||||
}
|
||||
switch (action) {
|
||||
case 'delete':
|
||||
doDelete();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
|
@ -21,9 +21,6 @@
|
|||
<i class="fa fa-bar-chart-o"></i> {% trans 'Assets' %}
|
||||
</a>
|
||||
</li>
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-default" href="{% url 'assets:system-user-update' pk=system_user.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
<li class="active">
|
||||
<a href="{% url 'assets:system-user-detail' pk=system_user.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'assets:system-user-asset' pk=system_user.id %}" class="text-center">
|
||||
<i class="fa fa-bar-chart-o"></i> {% trans 'Attached assets' %}
|
||||
</a>
|
||||
</li>
|
||||
{# <li>#}
|
||||
{# <a href="{% url 'assets:system-user-asset' pk=system_user.id %}" class="text-center">#}
|
||||
{# <i class="fa fa-bar-chart-o"></i> {% trans 'Attached assets' %}#}
|
||||
{# </a>#}
|
||||
{# </li>#}
|
||||
<li class="pull-right">
|
||||
<a class="btn btn-outline btn-default" href="{% url 'assets:system-user-update' pk=system_user.id %}"><i class="fa fa-edit"></i>{% trans 'Update' %}</a>
|
||||
</li>
|
||||
|
@ -130,6 +130,23 @@
|
|||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td width="50%">{% trans 'Push system user manually' %}:</td>
|
||||
<td>
|
||||
<span style="float: right">
|
||||
<button type="button" class="btn btn-primary btn-xs btn-push" style="width: 54px">{% trans 'Push' %}</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%">{% trans 'Test assets connective' %}:</td>
|
||||
<td>
|
||||
<span style="float: right">
|
||||
<button type="button" class="btn btn-primary btn-xs btn-test-connective" style="width: 54px">{% trans 'Test' %}</button>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{# <tr>#}
|
||||
{# <td width="50%">{% trans 'Change auth period' %}:</td>#}
|
||||
{# <td>#}
|
||||
|
@ -144,7 +161,7 @@
|
|||
</div>
|
||||
<div class="panel panel-info">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Clusters' %}
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Nodes' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<table class="table cluster_edit" id="add-asset2group">
|
||||
|
@ -152,9 +169,9 @@
|
|||
<form>
|
||||
<tr>
|
||||
<td colspan="2" class="no-borders">
|
||||
<select data-placeholder="{% trans 'Add to cluster' %}" id="cluster_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for cluster in cluster_remain %}
|
||||
<option value="{{ cluster.id }}" id="opt_{{ cluster.id }}" >{{ cluster.name }}</option>
|
||||
<select data-placeholder="{% trans 'Add to node' %}" id="cluster_selected" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||
{% for node in nodes_remain %}
|
||||
<option value="{{ node.id }}" id="opt_{{ node.id }}" >{{ node.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</td>
|
||||
|
@ -166,9 +183,9 @@
|
|||
</tr>
|
||||
</form>
|
||||
|
||||
{% for cluster in system_user.cluster.all %}
|
||||
{% for node in system_user.nodes.all %}
|
||||
<tr>
|
||||
<td ><b class="bdg_cluster" data-gid={{ cluster.id }}>{{ cluster.name }}</b></td>
|
||||
<td ><b class="bdg_node" data-gid={{ node.id }}>{{ node.name }}</b></td>
|
||||
<td>
|
||||
<button class="btn btn-danger pull-right btn-xs btn-remove-from-cluster" type="button"><i class="fa fa-minus"></i></button>
|
||||
</td>
|
||||
|
@ -201,7 +218,7 @@ function updateSystemUserCluster(clusters) {
|
|||
// change tr html of user groups.
|
||||
$('.cluster_edit tbody').append(
|
||||
'<tr>' +
|
||||
'<td><b class="bdg_cluster" data-gid="' + index + '">' + cluster_name + '</b></td>' +
|
||||
'<td><b class="bdg_node" data-gid="' + index + '">' + cluster_name + '</b></td>' +
|
||||
'<td><button class="btn btn-danger btn-xs pull-right btn-remove-from-cluster" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||
'</tr>'
|
||||
)
|
||||
|
@ -242,7 +259,7 @@ $(document).ready(function () {
|
|||
if (Object.keys(jumpserver.cluster_selected).length === 0) {
|
||||
return false;
|
||||
}
|
||||
var clusters = $('.bdg_cluster').map(function() {
|
||||
var clusters = $('.bdg_node').map(function() {
|
||||
return $(this).data('gid');
|
||||
}).get();
|
||||
$.map(jumpserver.cluster_selected, function(value, index) {
|
||||
|
@ -253,14 +270,14 @@ $(document).ready(function () {
|
|||
.on('click', '.btn-remove-from-cluster', function() {
|
||||
var $this = $(this);
|
||||
var $tr = $this.closest('tr');
|
||||
var $badge = $tr.find('.bdg_cluster');
|
||||
var $badge = $tr.find('.bdg_node');
|
||||
var gid = $badge.data('gid');
|
||||
var cluster_name = $badge.html() || $badge.text();
|
||||
$('#groups_selected').append(
|
||||
'<option value="' + gid + '" id="opt_' + gid + '">' + cluster_name + '</option>'
|
||||
);
|
||||
$tr.remove();
|
||||
var clusters = $('.bdg_cluster').map(function () {
|
||||
var clusters = $('.bdg_node').map(function () {
|
||||
return $(this).data('gid');
|
||||
}).get();
|
||||
updateSystemUserCluster(clusters);
|
||||
|
|
|
@ -35,8 +35,8 @@ urlpatterns = [
|
|||
# api.ClusterAddAssetsApi.as_view(), name='cluster-add-assets'),
|
||||
#url(r'^v1/cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/connective/$',
|
||||
# api.ClusterTestAssetsAliveApi.as_view(), name='cluster-test-connective'),
|
||||
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/clusters/$',
|
||||
api.AdminUserAddClustersApi.as_view(), name='admin-user-add-clusters'),
|
||||
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/nodes/$',
|
||||
api.ReplaceNodesAdminUserApi.as_view(), name='replace-nodes-admin-user'),
|
||||
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$',
|
||||
api.AdminUserTestConnectiveApi.as_view(), name='admin-user-connective'),
|
||||
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/push/$',
|
||||
|
|
|
@ -14,27 +14,11 @@ urlpatterns = [
|
|||
url(r'^asset/(?P<pk>[0-9a-zA-Z\-]{36})/$', views.AssetDetailView.as_view(), name='asset-detail'),
|
||||
url(r'^asset/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.AssetUpdateView.as_view(), name='asset-update'),
|
||||
url(r'^asset/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.AssetDeleteView.as_view(), name='asset-delete'),
|
||||
url(r'^asset-modal$', views.AssetModalListView.as_view(), name='asset-modal-list'),
|
||||
url(r'^asset/update/$', views.AssetBulkUpdateView.as_view(), name='asset-bulk-update'),
|
||||
|
||||
# User asset view
|
||||
url(r'^user-asset/$', views.UserAssetListView.as_view(), name='user-asset-list'),
|
||||
|
||||
# # Resource asset group url
|
||||
# url(r'^asset-group/$', views.AssetGroupListView.as_view(), name='asset-group-list'),
|
||||
# url(r'^asset-group/create/$', views.AssetGroupCreateView.as_view(), name='asset-group-create'),
|
||||
# url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]{36})/$', views.AssetGroupDetailView.as_view(), name='asset-group-detail'),
|
||||
# url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.AssetGroupUpdateView.as_view(), name='asset-group-update'),
|
||||
# url(r'^asset-group/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.AssetGroupDeleteView.as_view(), name='asset-group-delete'),
|
||||
|
||||
# Resource cluster url
|
||||
# url(r'^cluster/$', views.ClusterListView.as_view(), name='cluster-list'),
|
||||
# url(r'^cluster/create/$', views.ClusterCreateView.as_view(), name='cluster-create'),
|
||||
# url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/$', views.ClusterDetailView.as_view(), name='cluster-detail'),
|
||||
# url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/update/', views.ClusterUpdateView.as_view(), name='cluster-update'),
|
||||
# url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.ClusterDeleteView.as_view(), name='cluster-delete'),
|
||||
# url(r'^cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$', views.ClusterAssetsView.as_view(), name='cluster-assets'),
|
||||
|
||||
# Resource admin user url
|
||||
url(r'^admin-user/$', views.AdminUserListView.as_view(), name='admin-user-list'),
|
||||
url(r'^admin-user/create/$', views.AdminUserCreateView.as_view(), name='admin-user-create'),
|
||||
|
@ -50,14 +34,10 @@ urlpatterns = [
|
|||
url(r'^system-user/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.SystemUserUpdateView.as_view(), name='system-user-update'),
|
||||
url(r'^system-user/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.SystemUserDeleteView.as_view(), name='system-user-delete'),
|
||||
url(r'^system-user/(?P<pk>[0-9a-zA-Z\-]{36})/asset/$', views.SystemUserAssetView.as_view(), name='system-user-asset'),
|
||||
# url(r'^system-user/(?P<pk>[0-9a-zA-Z\-]{36})/asset-group$', views.SystemUserAssetGroupView.as_view(),
|
||||
# name='system-user-asset-group'),
|
||||
|
||||
url(r'^label/$', views.LabelListView.as_view(), name='label-list'),
|
||||
url(r'^label/create/$', views.LabelCreateView.as_view(), name='label-create'),
|
||||
url(r'^label/(?P<pk>[0-9a-zA-Z\-]{36})/update/$', views.LabelUpdateView.as_view(), name='label-update'),
|
||||
url(r'^label/(?P<pk>[0-9a-zA-Z\-]{36})/delete/$', views.LabelDeleteView.as_view(), name='label-delete'),
|
||||
|
||||
url(r'^tree/$', views.TreeView.as_view(), name='tree-view'),
|
||||
]
|
||||
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
# coding:utf-8
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views.generic import TemplateView, ListView, View
|
||||
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
|
||||
from django.urls import reverse_lazy
|
||||
from django.views.generic.detail import DetailView, SingleObjectMixin
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
|
||||
from common.const import create_success_msg, update_success_msg
|
||||
from .. import forms
|
||||
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
|
||||
from ..hands import AdminUserRequiredMixin
|
||||
|
||||
|
||||
__all__ = [
|
||||
'ClusterListView', 'ClusterCreateView', 'ClusterUpdateView',
|
||||
'ClusterDetailView', 'ClusterDeleteView', 'ClusterAssetsView',
|
||||
]
|
||||
|
||||
|
||||
class ClusterListView(AdminUserRequiredMixin, TemplateView):
|
||||
template_name = 'assets/cluster_list.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Cluster list'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class ClusterCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
|
||||
model = Cluster
|
||||
form_class = forms.ClusterForm
|
||||
template_name = 'assets/cluster_create_update.html'
|
||||
success_url = reverse_lazy('assets:cluster-list')
|
||||
success_message = create_success_msg
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('assets'),
|
||||
'action': _('Create cluster'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
def form_valid(self, form):
|
||||
cluster = form.save()
|
||||
cluster.created_by = self.request.user.username
|
||||
cluster.save()
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class ClusterUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
|
||||
model = Cluster
|
||||
form_class = forms.ClusterForm
|
||||
template_name = 'assets/cluster_create_update.html'
|
||||
context_object_name = 'cluster'
|
||||
success_url = reverse_lazy('assets:cluster-list')
|
||||
success_message = update_success_msg
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('assets'),
|
||||
'action': _('Update Cluster'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class ClusterDetailView(AdminUserRequiredMixin, DetailView):
|
||||
model = Cluster
|
||||
template_name = 'assets/cluster_detail.html'
|
||||
context_object_name = 'cluster'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
admin_user_list = AdminUser.objects.exclude()
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Cluster detail'),
|
||||
'admin_user_list': admin_user_list,
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class ClusterAssetsView(AdminUserRequiredMixin, DetailView):
|
||||
model = Cluster
|
||||
template_name = 'assets/cluster_assets.html'
|
||||
context_object_name = 'cluster'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
|
||||
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Asset detail'),
|
||||
'groups': AssetGroup.objects.all(),
|
||||
'system_users': SystemUser.objects.all(),
|
||||
'assets_remain': assets_remain,
|
||||
'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain],
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class ClusterDeleteView(AdminUserRequiredMixin, DeleteView):
|
||||
model = Cluster
|
||||
template_name = 'delete_confirm.html'
|
||||
success_url = reverse_lazy('assets:cluster-list')
|
|
@ -1,97 +0,0 @@
|
|||
# coding:utf-8
|
||||
from __future__ import absolute_import, unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views.generic import TemplateView, ListView, View
|
||||
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
|
||||
from django.urls import reverse_lazy
|
||||
from django.views.generic.detail import DetailView, SingleObjectMixin
|
||||
from django.shortcuts import get_object_or_404, reverse, redirect
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
|
||||
from common.const import create_success_msg, update_success_msg
|
||||
from .. import forms
|
||||
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
|
||||
from ..hands import AdminUserRequiredMixin
|
||||
|
||||
|
||||
__all__ = [
|
||||
'AssetGroupCreateView', 'AssetGroupDetailView',
|
||||
'AssetGroupUpdateView', 'AssetGroupListView',
|
||||
'AssetGroupDeleteView',
|
||||
]
|
||||
|
||||
|
||||
class AssetGroupCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
|
||||
model = AssetGroup
|
||||
form_class = forms.AssetGroupForm
|
||||
template_name = 'assets/asset_group_create.html'
|
||||
success_url = reverse_lazy('assets:asset-group-list')
|
||||
success_message = create_success_msg
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Create asset group'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
def form_valid(self, form):
|
||||
group = form.save()
|
||||
group.created_by = self.request.user.username
|
||||
group.save()
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
class AssetGroupListView(AdminUserRequiredMixin, TemplateView):
|
||||
template_name = 'assets/asset_group_list.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Asset group list'),
|
||||
'assets': Asset.objects.all(),
|
||||
'system_users': SystemUser.objects.all(),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(AssetGroupListView, self).get_context_data(**kwargs)
|
||||
|
||||
|
||||
class AssetGroupDetailView(AdminUserRequiredMixin, DetailView):
|
||||
model = AssetGroup
|
||||
template_name = 'assets/asset_group_detail.html'
|
||||
context_object_name = 'asset_group'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
assets_remain = Asset.objects.exclude(groups__in=[self.object])
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Asset group detail'),
|
||||
'assets_remain': assets_remain,
|
||||
'assets': self.object.assets.all(),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class AssetGroupUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView):
|
||||
model = AssetGroup
|
||||
form_class = forms.AssetGroupForm
|
||||
template_name = 'assets/asset_group_create.html'
|
||||
success_url = reverse_lazy('assets:asset-group-list')
|
||||
success_message = update_success_msg
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Create asset group'),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class AssetGroupDeleteView(AdminUserRequiredMixin, DeleteView):
|
||||
template_name = 'delete_confirm.html'
|
||||
model = AssetGroup
|
||||
success_url = reverse_lazy('assets:asset-group-list')
|
|
@ -1,8 +1,5 @@
|
|||
# coding:utf-8
|
||||
from .asset import *
|
||||
# from .group import *
|
||||
# from .cluster import *
|
||||
from .system_user import *
|
||||
from .admin_user import *
|
||||
from .label import *
|
||||
from .node import *
|
||||
|
|
|
@ -10,7 +10,7 @@ from django.views.generic.detail import DetailView, SingleObjectMixin
|
|||
|
||||
from common.const import create_success_msg, update_success_msg
|
||||
from .. import forms
|
||||
from ..models import AdminUser, Cluster
|
||||
from ..models import AdminUser, Node
|
||||
from ..hands import AdminUserRequiredMixin
|
||||
|
||||
__all__ = [
|
||||
|
@ -77,6 +77,7 @@ class AdminUserDetailView(AdminUserRequiredMixin, DetailView):
|
|||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Admin user detail'),
|
||||
'nodes': Node.objects.all()
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
|
|
@ -34,8 +34,7 @@ from ..hands import AdminUserRequiredMixin
|
|||
__all__ = [
|
||||
'AssetListView', 'AssetCreateView', 'AssetUpdateView',
|
||||
'UserAssetListView', 'AssetBulkUpdateView', 'AssetDetailView',
|
||||
'AssetModalListView', 'AssetDeleteView', 'AssetExportView',
|
||||
'BulkImportAssetView',
|
||||
'AssetDeleteView', 'AssetExportView', 'BulkImportAssetView',
|
||||
]
|
||||
logger = get_logger(__file__)
|
||||
|
||||
|
@ -102,22 +101,22 @@ class AssetCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
|
|||
return create_success_msg % ({"name": cleaned_data["hostname"]})
|
||||
|
||||
|
||||
class AssetModalListView(AdminUserRequiredMixin, ListView):
|
||||
paginate_by = settings.DISPLAY_PER_PAGE
|
||||
model = Asset
|
||||
context_object_name = 'asset_modal_list'
|
||||
template_name = 'assets/asset_modal_list.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
assets = Asset.objects.all()
|
||||
assets_id = self.request.GET.get('assets_id', '')
|
||||
assets_id_list = [i for i in assets_id.split(',') if i.isdigit()]
|
||||
context = {
|
||||
'all_assets': assets_id_list,
|
||||
'assets': assets
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
# class AssetModalListView(AdminUserRequiredMixin, ListView):
|
||||
# paginate_by = settings.DISPLAY_PER_PAGE
|
||||
# model = Asset
|
||||
# context_object_name = 'asset_modal_list'
|
||||
# template_name = 'assets/_asset_list_modal.html'
|
||||
#
|
||||
# def get_context_data(self, **kwargs):
|
||||
# assets = Asset.objects.all()
|
||||
# assets_id = self.request.GET.get('assets_id', '')
|
||||
# assets_id_list = [i for i in assets_id.split(',') if i.isdigit()]
|
||||
# context = {
|
||||
# 'all_assets': assets_id_list,
|
||||
# 'assets': assets
|
||||
# }
|
||||
# kwargs.update(context)
|
||||
# return super().get_context_data(**kwargs)
|
||||
|
||||
|
||||
class AssetBulkUpdateView(AdminUserRequiredMixin, ListView):
|
||||
|
@ -191,14 +190,11 @@ class AssetDetailView(DetailView):
|
|||
template_name = 'assets/asset_detail.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
asset_groups = self.object.groups.all()
|
||||
nodes_remain = Node.objects.exclude(assets=self.object)
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Asset detail'),
|
||||
'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all()
|
||||
if asset_group not in asset_groups],
|
||||
'asset_groups': asset_groups,
|
||||
'system_users_all': SystemUser.objects.all(),
|
||||
'nodes_remain': nodes_remain,
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from django.views.generic import TemplateView
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from common.mixins import AdminUserRequiredMixin
|
||||
from ..models import Label
|
||||
|
||||
|
||||
__all__ = ['TreeView']
|
||||
|
||||
|
||||
class TreeView(AdminUserRequiredMixin, TemplateView):
|
||||
template_name = 'assets/tree.html'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('Tree view'),
|
||||
'labels': Label.objects.all(),
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
|
@ -9,7 +9,7 @@ from django.views.generic.detail import DetailView
|
|||
|
||||
from common.const import create_success_msg, update_success_msg
|
||||
from ..forms import SystemUserForm
|
||||
from ..models import SystemUser, Cluster
|
||||
from ..models import SystemUser, Node
|
||||
from ..hands import AdminUserRequiredMixin
|
||||
|
||||
|
||||
|
@ -73,6 +73,7 @@ class SystemUserDetailView(AdminUserRequiredMixin, DetailView):
|
|||
context = {
|
||||
'app': _('Assets'),
|
||||
'action': _('System user detail'),
|
||||
'nodes_remain': Node.objects.exclude(systemuser=self.object)
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super().get_context_data(**kwargs)
|
||||
|
|
|
@ -191,7 +191,7 @@ function updateGroup(groups) {
|
|||
}
|
||||
|
||||
jumpserver.assets_selected = {};
|
||||
jumpserver.groups_selected = {};
|
||||
jumpserver.nodes_selected = {};
|
||||
|
||||
$(document).ready(function () {
|
||||
$('.select2.asset').select2()
|
||||
|
@ -206,11 +206,11 @@ $(document).ready(function () {
|
|||
$('.select2.group').select2()
|
||||
.on('select2:select', function(evt) {
|
||||
var data = evt.params.data;
|
||||
jumpserver.groups_selected[data.id] = data.text;
|
||||
jumpserver.nodes_selected[data.id] = data.text;
|
||||
})
|
||||
.on('select2:unselect', function(evt) {
|
||||
var data = evt.params.data;
|
||||
delete jumpserver.groups_selected[data.id]
|
||||
delete jumpserver.nodes_selected[data.id]
|
||||
})
|
||||
})
|
||||
.on('click', '.btn-add-assets', function () {
|
||||
|
@ -232,7 +232,7 @@ $(document).ready(function () {
|
|||
removeAssets(assets)
|
||||
})
|
||||
.on('click', '#btn-add-group', function () {
|
||||
if (Object.keys(jumpserver.groups_selected).length === 0) {
|
||||
if (Object.keys(jumpserver.nodes_selected).length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,7 @@ $(document).ready(function () {
|
|||
return $(this).data('gid');
|
||||
}).get();
|
||||
|
||||
$.map(jumpserver.groups_selected, function(group_name, index) {
|
||||
$.map(jumpserver.nodes_selected, function(group_name, index) {
|
||||
groups.push(index);
|
||||
$('#opt_' + index).remove();
|
||||
$('.group_edit tbody').append(
|
||||
|
|
|
@ -85,7 +85,7 @@ function initTable() {
|
|||
ele: $('#permission_list_table'),
|
||||
columnDefs: [
|
||||
{targets: 1, createdCell: function (td, cellData) {
|
||||
var html = '<a href="{% url 'assets:tree-view' %}?node=99899">' + cellData.name + '</a>';
|
||||
var html = '<a href="{% url 'assets:asset-list' %}?node=99899">' + cellData.name + '</a>';
|
||||
$(td).html(html.replace("99899", cellData.pk));
|
||||
}},
|
||||
{targets: 2, createdCell: function (td, cellData) {
|
||||
|
@ -178,9 +178,9 @@ function initTree() {
|
|||
$.get("{% url 'api-assets:node-list' %}", function(data, status){
|
||||
$.each(data, function (index, value) {
|
||||
value["pId"] = value["parent"];
|
||||
if (value["key"] === "0") {
|
||||
value["open"] = true;
|
||||
}
|
||||
{#if (value["key"] === "0") {#}
|
||||
value["open"] = true;
|
||||
{# }#}
|
||||
value["name"] = value["value"]
|
||||
});
|
||||
zNodes = data;
|
||||
|
|
|
@ -150,7 +150,7 @@
|
|||
{% block custom_foot_js %}
|
||||
<script>
|
||||
jumpserver.users_selected = {};
|
||||
jumpserver.groups_selected = {};
|
||||
jumpserver.nodes_selected = {};
|
||||
|
||||
function addUsers(users) {
|
||||
var the_url = "{% url 'api-perms:asset-permission-add-user' pk=asset_permission.id %}";
|
||||
|
@ -206,11 +206,11 @@ $(document).ready(function () {
|
|||
$('.select2.user-group').select2()
|
||||
.on('select2:select', function(evt) {
|
||||
var data = evt.params.data;
|
||||
jumpserver.groups_selected[data.id] = data.text;
|
||||
jumpserver.nodes_selected[data.id] = data.text;
|
||||
})
|
||||
.on('select2:unselect', function(evt) {
|
||||
var data = evt.params.data;
|
||||
delete jumpserver.groups_selected[data.id]
|
||||
delete jumpserver.nodes_selected[data.id]
|
||||
})
|
||||
}).on('click', '.btn-add-user', function () {
|
||||
if (Object.keys(jumpserver.users_selected).length === 0) {
|
||||
|
@ -229,7 +229,7 @@ $(document).ready(function () {
|
|||
var users = [user_id];
|
||||
removeUser(users)
|
||||
}).on('click', '#btn-add-group', function () {
|
||||
if (Object.keys(jumpserver.groups_selected).length === 0) {
|
||||
if (Object.keys(jumpserver.nodes_selected).length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -237,7 +237,7 @@ $(document).ready(function () {
|
|||
return $(this).data('gid');
|
||||
}).get();
|
||||
|
||||
$.map(jumpserver.groups_selected, function(group_name, index) {
|
||||
$.map(jumpserver.nodes_selected, function(group_name, index) {
|
||||
groups.push(index);
|
||||
$('#opt_' + index).remove();
|
||||
$('.group_edit tbody').append(
|
||||
|
|
|
@ -222,7 +222,7 @@
|
|||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
jumpserver.groups_selected = {};
|
||||
jumpserver.nodes_selected = {};
|
||||
|
||||
function updateUserGroups(groups) {
|
||||
var the_url = "{% url 'api-users:user-update-group' pk=user_object.id %}";
|
||||
|
@ -233,7 +233,7 @@ function updateUserGroups(groups) {
|
|||
// remove all the selected groups from select > option and rendered ul element;
|
||||
$('.select2-selection__rendered').empty();
|
||||
$('#groups_selected').val('');
|
||||
$.map(jumpserver.groups_selected, function(group_name, index) {
|
||||
$.map(jumpserver.nodes_selected, function(group_name, index) {
|
||||
$('#opt_' + index).remove();
|
||||
// change tr html of user groups.
|
||||
$('.group_edit tbody').append(
|
||||
|
@ -244,7 +244,7 @@ function updateUserGroups(groups) {
|
|||
)
|
||||
});
|
||||
// clear jumpserver.groups_selected
|
||||
jumpserver.groups_selected = {};
|
||||
jumpserver.nodes_selected = {};
|
||||
};
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
|
@ -257,11 +257,11 @@ $(document).ready(function() {
|
|||
$('.select2').select2()
|
||||
.on('select2:select', function(evt) {
|
||||
var data = evt.params.data;
|
||||
jumpserver.groups_selected[data.id] = data.text;
|
||||
jumpserver.nodes_selected[data.id] = data.text;
|
||||
})
|
||||
.on('select2:unselect', function(evt) {
|
||||
var data = evt.params.data;
|
||||
delete jumpserver.groups_selected[data.id];
|
||||
delete jumpserver.nodes_selected[data.id];
|
||||
})
|
||||
})
|
||||
.on('click', '#is_active', function() {
|
||||
|
@ -291,13 +291,13 @@ $(document).ready(function() {
|
|||
{# });#}
|
||||
{# });#}
|
||||
.on('click', '#btn_join_group', function() {
|
||||
if (Object.keys(jumpserver.groups_selected).length === 0) {
|
||||
if (Object.keys(jumpserver.nodes_selected).length === 0) {
|
||||
return false;
|
||||
}
|
||||
var groups = $('.bdg_group').map(function() {
|
||||
return $(this).data('gid');
|
||||
}).get();
|
||||
$.map(jumpserver.groups_selected, function(value, index) {
|
||||
$.map(jumpserver.nodes_selected, function(value, index) {
|
||||
groups.push(index);
|
||||
$('#opt_' + index).remove();
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue