提交 b4e1ac19 编写于 作者: baltery's avatar baltery

[Bugfix] 修复资产模块中一些bug

上级 a308000d
......@@ -74,23 +74,30 @@ class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView):
permission_classes = (IsSuperUser,)
class AssetGroupUpdateApi(generics.RetrieveUpdateAPIView):
class GroupUpdateAssetsApi(generics.RetrieveUpdateAPIView):
"""
Asset group, update it's asset member
"""
queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupUpdateSerializer
serializer_class = serializers.GroupUpdateAssetsSerializer
permission_classes = (IsSuperUser,)
class AssetGroupUpdateSystemUserApi(generics.RetrieveUpdateAPIView):
"""
Asset group push system user
"""
class GroupAddAssetsApi(generics.UpdateAPIView):
queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupUpdateSystemUserSerializer
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)
class ClusterUpdateAssetsApi(generics.RetrieveUpdateAPIView):
"""
......@@ -110,6 +117,24 @@ class ClusterViewSet(IDInFilterMixin, BulkModelViewSet):
permission_classes = (IsSuperUser,)
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)
class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet):
"""
Admin user api set, for add,delete,update,list,retrieve resource
......@@ -119,52 +144,31 @@ class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet):
permission_classes = (IsSuperUser,)
class SystemUserViewSet(IDInFilterMixin, BulkModelViewSet):
"""
System user api set, for add,delete,update,list,retrieve resource
"""
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserSerializer
permission_classes = (IsSuperUserOrAppUser,)
class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
"""
Asset update it's system user
when update then push system user to asset.
"""
queryset = Asset.objects.all()
serializer_class = serializers.AssetUpdateSystemUserSerializer
class AdminUserAddClustersApi(generics.UpdateAPIView):
queryset = AdminUser.objects.all()
serializer_class = serializers.AdminUserUpdateClusterSerializer
permission_classes = (IsSuperUser,)
def patch(self, request, *args, **kwargs):
asset = self.get_object()
old_system_users = set(asset.system_users.all())
response = super(SystemUserUpdateApi, self).patch(request, *args, **kwargs)
system_users_new = set(asset.system_users.all())
system_users = system_users_new - old_system_users
system_users = [system_user._to_secret_json() for system_user in system_users]
push_users.delay([asset._to_secret_json()], system_users)
return response
class SystemUserUpdateAssetsApi(generics.RetrieveUpdateAPIView):
"""
System user update it's assets
"""
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserUpdateAssetsSerializer
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()
return Response({"msg": "ok"})
else:
return Response({'error': serializer.errors}, status=400)
class SystemUserUpdateAssetGroupApi(generics.RetrieveUpdateAPIView):
class SystemUserViewSet(IDInFilterMixin, BulkModelViewSet):
"""
System user update asset group
System user api set, for add,delete,update,list,retrieve resource
"""
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserUpdateAssetGroupSerializer
permission_classes = (IsSuperUser,)
serializer_class = serializers.SystemUserSerializer
permission_classes = (IsSuperUserOrAppUser,)
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
......@@ -229,22 +233,3 @@ class AssetAdminUserTestView(AssetRefreshHardwareView):
else:
return Response('0', status=502)
class AssetGroupPushSystemUserView(generics.UpdateAPIView):
"""
Asset group push system user api
"""
queryset = AssetGroup.objects.all()
permission_classes = (IsSuperUser,)
serializer_class = serializers.AssetSerializer
def patch(self, request, *args, **kwargs):
asset_group = self.get_object()
assets = asset_group.assets.all()
system_user_id = self.request.data['system_user']
system_user = get_object_or_none(SystemUser, id=system_user_id)
if not assets or not system_user:
return Response('Invalid system user id or asset group id', status=404)
task = push_users.delay([asset._to_secret_json() for asset in assets],
system_user._to_secret_json())
return Response(task.id)
......@@ -61,6 +61,7 @@ class AssetBulkUpdateForm(forms.ModelForm):
required=True,
help_text='* required',
label=_('Select assets'),
choices=[(asset.id, asset.hostname) for asset in Asset.objects.all()],
widget=forms.SelectMultiple(
attrs={
'class': 'select2',
......@@ -68,7 +69,12 @@ class AssetBulkUpdateForm(forms.ModelForm):
}
)
)
port = forms.IntegerField(min_value=1, max_value=65535, required=False, label=_('Port'))
port = forms.IntegerField(
label=_('Port'),
required=False,
min_value=1,
max_value=65535,
)
class Meta:
model = Asset
......@@ -81,9 +87,16 @@ class AssetBulkUpdateForm(forms.ModelForm):
}
def save(self, commit=True):
cleaned_data = {k: v for k, v in self.cleaned_data.items() if v is not None}
changed_fields = []
for field in self._meta.fields:
if self.data.get(field) is not None:
changed_fields.append(field)
cleaned_data = {k: v for k, v in self.cleaned_data.items()
if k in changed_fields}
print(cleaned_data)
assets_id = cleaned_data.pop('assets')
groups = cleaned_data.pop('groups')
groups = cleaned_data.pop('groups', [])
assets = Asset.objects.filter(id__in=assets_id)
assets.update(**cleaned_data)
if groups:
......@@ -153,17 +166,18 @@ class AdminUserForm(forms.ModelForm):
def save(self, commit=True):
# Because we define custom field, so we need rewrite :method: `save`
admin_user = super(AdminUserForm, self).save(commit=commit)
admin_user = super().save(commit=commit)
password = self.cleaned_data['password']
private_key = self.cleaned_data['private_key_file']
public_key = None
if not password:
password = None
if password:
admin_user.password = password
if private_key:
public_key = ssh_pubkey_gen(private_key)
admin_user.private_key = private_key
admin_user.public_key = public_key
admin_user.save()
admin_user.set_auth(password=password, public_key=public_key, private_key=private_key)
return admin_user
def clean_private_key_file(self):
......
......@@ -47,7 +47,7 @@ class AssetUpdateSystemUserSerializer(serializers.ModelSerializer):
fields = ['id', 'system_users']
class AssetGroupUpdateSerializer(serializers.ModelSerializer):
class GroupUpdateAssetsSerializer(serializers.ModelSerializer):
"""
资产组更新需要的数据结构
"""
......@@ -58,17 +58,6 @@ class AssetGroupUpdateSerializer(serializers.ModelSerializer):
fields = ['id', 'assets']
class AssetGroupUpdateSystemUserSerializer(serializers.ModelSerializer):
"""
资产组更新系统用户定义的数据结构
"""
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
class Meta:
model = AssetGroup
fields = ['id', 'system_users']
class ClusterUpdateAssetsSerializer(serializers.ModelSerializer):
"""
集群更新资产数据结构
......@@ -135,35 +124,24 @@ class SystemUserSerializer(serializers.ModelSerializer):
return amount
class AssetSystemUserSerializer(serializers.ModelSerializer):
"""
查看授权的资产系统用户的数据结构,这个和AssetSerializer不同,字段少
"""
class Meta:
model = SystemUser
fields = ('id', 'name', 'username', 'priority', 'protocol', 'comment',)
class SystemUserUpdateAssetsSerializer(serializers.ModelSerializer):
class AdminUserUpdateClusterSerializer(serializers.ModelSerializer):
"""
系统用户更新关联资产的数据结构
管理用户更新关联到的集群
"""
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
clusters = serializers.PrimaryKeyRelatedField(many=True, queryset=Cluster.objects.all())
class Meta:
model = SystemUser
fields = ['id', 'assets']
model = AdminUser
fields = ['id', 'clusters']
class SystemUserUpdateAssetGroupSerializer(serializers.ModelSerializer):
class AssetSystemUserSerializer(serializers.ModelSerializer):
"""
系统用户更新资产组的api
查看授权的资产系统用户的数据结构,这个和AssetSerializer不同,字段少
"""
asset_groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
class Meta:
model = SystemUser
fields = ['id', 'asset_groups']
fields = ('id', 'name', 'username', 'priority', 'protocol', 'comment',)
class SystemUserSimpleSerializer(serializers.ModelSerializer):
......
......@@ -102,12 +102,12 @@
<i class="fa fa-info-circle"></i> {% trans 'Using this as cluster admin user' %}
</div>
<div class="panel-body">
<table class="table group_edit" id="add-asset2group">
<table class="table group_edit" id="table-clusters">
<tbody>
<form>
<tr>
<td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Select cluster' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
<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>
{% endfor %}
......@@ -116,17 +116,14 @@
</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-add-cluster">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
{% for cluster in admin_user.cluster_set.all %}
<tr>
<td ><b class="bdg_group" data-gid={{ cluster.id }}>{{ cluster.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>
</td>
<td ><b class="bdg_cluster" data-gid={{ cluster.id }}>{{ cluster.name }}</b></td>
</tr>
{% endfor %}
</tbody>
......@@ -161,74 +158,48 @@ Array.prototype.unique = function(){
}
return res;
};
function objectRemove(obj, name, url, data) {
function doRemove() {
var body = data;
var success = function() {
swal('Remove!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Remove"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
function bindToCluster(clusters) {
var the_url = "{% url 'api-assets:admin-user-add-clusters' pk=admin_user.id %}";
var body = {
clusters: clusters
};
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) {
console.log(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>'
)
});
}
swal({
title: 'Are you sure remove ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doRemove()
$.map(jumpserver.cluster_selected, function(value, index) {
$('#opt_' + index).remove();
});
// clear jumpserver.groups_selected
jumpserver.cluster_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
function adminUserDelete(name, url) {
function doDelete() {
var body = {};
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
window.location.href="{% url 'assets:cluster-list' %}";
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'DELETE',
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
jumpserver.assets_selected = {};
jumpserver.asset_groups_selected = {};
jumpserver.cluster_selected = {};
$(document).ready(function () {
$('.select2').select2();
$('.select2').select2().on('select2:select', function(evt) {
var data = evt.params.data;
jumpserver.cluster_selected[data.id] = data.text;
}).on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.cluster_selected[data.id]
});
})
.on('click', '.btn-delete-admin-user', function () {
var $this = $(this);
......@@ -238,5 +209,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) {
return false;
}
var clusters = [];
$.map(jumpserver.cluster_selected, function(value, index) {
clusters.push(index);
});
bindToCluster(clusters)
})
</script>
{% endblock %}
......@@ -247,7 +247,6 @@
{% block custom_foot_js %}
<script>
jumpserver.groups_selected = {};
jumpserver.system_user_selected = {};
function updateAssetGroups(groups) {
var the_url = "{% url 'api-assets:asset-update-group' pk=asset.id %}";
var body = {
......
......@@ -94,39 +94,34 @@
{% block custom_foot_js %}
<script>
jumpserver.assets_selected = {};
function updateGroupAssets(assets) {
var the_url = "{}";
function addAssets(assets) {
var the_url = "{% url 'api-assets:group-add-assets' pk=asset_group.id %}";
var body = {
assets: Object.assign([], assets)
assets: assets
};
var $data_table = $("#asset_list_table").DataTable();
var success = function(data) {
$('.select2-selection__rendered').empty();
$.map(jumpserver.assets_selected, function(asset_ip, index) {
$('#opt_' + index).remove();
$data_table.ajax.reload();
});
jumpserver.groups_selected = {};
$data_table.ajax.reload();
jumpserver.groups_selected = {};
};
console.log(body);
//APIUpdateAttr({
// url: the_url,
// body: JSON.stringify(body),
// method: 'PUT',
// success: success
//});
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PUT',
success: success
});
}
function leaveGroup(obj, name, url, data) {
function doDelete() {
var body = data;
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
console.log("Remove failed")
};
APIUpdateAttr({
url: url,
......@@ -135,19 +130,6 @@ function leaveGroup(obj, name, url, data) {
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
Array.prototype.remove = function(val) {
......@@ -188,13 +170,13 @@ function initTable() {
}},
{targets: 5, 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_asset_delete" data-aid="{{ DEFAULT_PK }}">{% trans "Remove" %}</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: "type" }, {data: "is_active" }, {data: "id"}],
{data: "get_type_display" }, {data: "is_connective" }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
......@@ -208,7 +190,6 @@ $(document).ready(function () {
.on('select2:select', function(evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
console.log(jumpserver.assets_selected)
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
......@@ -223,22 +204,26 @@ $(document).ready(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);
});
updateGroupAssets(jumpserver.assets_selected);
addAssets(assets_id);
})
.on('click', '.btn-leave-group', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:asset-groups-update' pk=asset_group.id %}";
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(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
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);
console.log(assets);
var data = {"assets": assets};
leaveGroup($this, name, the_url, data);
})
......
......@@ -21,19 +21,6 @@
<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>
</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_group_bulk_update_modal.html' %}
{% endblock %}
{% block content_bottom_left %}{% endblock %}
......
......@@ -45,17 +45,15 @@
</div>
<div class="ibox-content">
<table class="table table-striped table-bordered table-hover " id="cluster_assets_table" >
<table class="table table-hover " id="cluster_assets_table" >
<thead>
<tr>
<th class="text-center">
<input type="checkbox" id="check_all" class="ipt_check_all" >
</th>
<th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th>
<th>{% trans 'Type' %}</th>
<th>{% trans 'Valid' %}</th>
<th>{% trans 'Type' %}</th>
<th>{% trans 'Alive' %}</th>
<th>{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
......@@ -84,7 +82,7 @@
</tr>
<tr class="no-borders-tr">
<td colspan="2">
<button type="button" class="btn btn-primary btn-sm btn-asset-attach">{% trans 'Confirm' %}</button>
<button type="button" class="btn btn-primary btn-sm btn-add-assets">{% trans 'Confirm' %}</button>
</td>
</tr>
</form>
......@@ -112,18 +110,15 @@ Array.prototype.remove = function(val) {
}
};
function updateClusterAssets(assets) {
var the_url = "{% url 'api-assets:cluster-update-assets' pk=cluster.id %}";
function addAssets(assets) {
var the_url = "{% url 'api-assets:cluster-add-assets' pk=cluster.id %}";
var body = {
assets: Object.assign([], assets)
assets: assets
};
var $data_table = $("#cluster_assets_table").DataTable();
var success = function(data) {
$('.select2-selection__rendered').empty();
$.map(jumpserver.assets_selected, function(asset_ip, index) {
$('#opt_' + index).remove();
$data_table.ajax.reload();
});
$data_table.ajax.reload();
jumpserver.groups_selected = {};
};
APIUpdateAttr({
......@@ -134,22 +129,6 @@ function updateClusterAssets(assets) {
});
}
function deleteClusterAssets(assets) {
var the_url = "{% url 'api-assets:cluster-update-assets' pk=cluster.id %}";
var body = {
assets: Object.assign([], assets)
};
var $data_table = $("#cluster_assets_table").DataTable();
var success = function(data) {
$data_table.ajax.reload();
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PUT',
success: success
});
}
function initTable() {
var options = {
......@@ -157,23 +136,29 @@ function initTable() {
buttons: [],
order: [],
columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) {
{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: 5, createdCell: function (td, cellData) {
{targets: 4, 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: 5, 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: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "type" }, {data: "is_active" }],
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "get_type_display" }, {data: "is_connective" }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
}
$(document).ready(function () {
......@@ -189,166 +174,16 @@ $(document).ready(function () {
initTable();
})
.on('click', '.btn-asset-attach', function () {
.on('click', '.btn-add-assets', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
var assets=[];
var $data_table = $("#cluster_assets_table").DataTable();
$.ajax({
url: '{% url "api-assets:asset-list" %}',
method: 'GET',
data: {"cluster_id": {{ cluster.id }}},
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
updateClusterAssets(assets);
}
});
})
.on('click', '#btn_bulk_update', function () {
var action = $("#slct_bulk_update").val();
var $data_table = $("#cluster_assets_table").DataTable();
var id_list = [];
var plain_id_list = [];
var assets = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
var assets_id = [];
$.map(jumpserver.assets_selected, function(value, index) {
assets_id.push(index);
});
if (id_list === []) {
return false;
}
$.ajax({
url: '{% url "api-assets:asset-list" %}',
data: {"cluster_id": {{ cluster.id }}},
dataType: 'json',
method: 'GET',
success: function (result) {
for (var i in result) {
if (!isNaN(result[i]['id'])) {
assets.push(result[i]['id']);
}
}
for (var j in plain_id_list) {
assets.remove(plain_id_list[j])
}
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");
$('#cluster_assets_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Asset Deleting failed.' %}";
swal("{% trans 'Asset Delete' %}", msg, "error");
};
var url_delete = "{% url 'api-assets:cluster-update-assets' pk=cluster.id %}";
var body = {
assets: Object.assign([], assets)
};
APIUpdateAttr({url: url_delete, body: JSON.stringify(body), method: 'PUT', success: success, error: fail});
jumpserver.checked = false;
});
}
function doUpdate() {
$('#asset_bulk_update_modal').modal('show');
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
}
});
addAssets(assets_id);
})
.on('click', '#btn_asset_bulk_update', function () {
var json_data = $("#fm_asset_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.groups != undefined) {
body.groups = json_data.groups;
}
if (typeof body.groups === 'string') {
body.groups = [parseInt(body.groups)]
} else if(typeof body.groups === 'array') {
var new_groups = body.groups.map(Number);
body.groups = new_groups;
}
if (json_data.users != undefined) {
body.users = json_data.users;
}
if (typeof body.users === 'string') {
body.users = [parseInt(body.users)]
} else if(typeof body.users === 'array') {
var new_users = body.users.map(Number);
body.users = new_users;
}
if (json_data.tags != undefined) {
body.tags = json_data.tags;
}
if (typeof body.tags == 'string') {
body.tags = [parseInt(body.tags)];
} else if (typeof body.tags === 'array') {
var new_tags = body.tags.map(Number);
body.tags = new_tags;
}
var $data_table = $('#asset_list_table').DataTable();
var post_list = [];
$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-list' %}";
var success = function() {
var msg = "{% trans 'The selected assets has been updated successfully.' %}";
swal("{% trans 'Asset Updated' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});
$('#asset_bulk_update_modal').modal('hide');
});
</script>
{% endblock %}
......@@ -27,18 +27,6 @@
<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>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
......
......@@ -19,37 +19,22 @@ urlpatterns = [
name='system-user-auth-info'),
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/groups/$',
api.AssetUpdateGroupApi.as_view(), name='asset-update-group'),
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/refresh/$',
api.AssetRefreshHardwareView.as_view(), name='asset-refresh'),
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/admin-user-test/$',
api.AssetAdminUserTestView.as_view(), name='asset-admin-user-test'),
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/system-users/$',
api.SystemUserUpdateApi.as_view(), name='asset-update-system-users'),
url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/push-system-user/$',
api.AssetGroupPushSystemUserView.as_view(), name='asset-group-push-system-user'),
# update the system users, which add and delete the asset to the system user
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$',
api.SystemUserUpdateAssetsApi.as_view(), name='systemuser-update-assets'),
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/groups/$',
api.SystemUserUpdateAssetGroupApi.as_view(), name='systemuser-update-assetgroups'),
# update the asset group, which add or delete the asset to the group
url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$',
api.AssetGroupUpdateApi.as_view(), name='asset-groups-update'),
# update the asset group, and add or delete the system_user to the group
url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/system-users/$',
api.AssetGroupUpdateSystemUserApi.as_view(), name='asset-groups-update-systemusers'),
api.GroupUpdateAssetsApi.as_view(), name='group-update-assets'),
url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$',
api.GroupAddAssetsApi.as_view(), name='group-add-assets'),
# update the Cluster, and add or delete the assets to the Cluster
url(r'^v1/cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$',
api.ClusterUpdateAssetsApi.as_view(), name='cluster-update-assets'),
url(r'^v1/cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$',
api.ClusterAddAssetsApi.as_view(), name='cluster-add-assets'),
url(r'^v1/admin-user/(?P<pk>[0-9a-zA-Z\-]{36})/clusters/$',
api.AdminUserAddClustersApi.as_view(), name='admin-user-add-clusters'),
]
urlpatterns += router.urls
......
......@@ -24,7 +24,7 @@ from django.shortcuts import redirect
from common.mixins import JSONResponseMixin
from common.utils import get_object_or_none, get_logger
from common.utils import get_object_or_none, get_logger, is_uuid
from .. import forms
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
from ..hands import AdminUserRequiredMixin
......@@ -112,16 +112,18 @@ class AssetBulkUpdateView(AdminUserRequiredMixin, ListView):
form_class = forms.AssetBulkUpdateForm
template_name = 'assets/asset_bulk_update.html'
success_url = reverse_lazy('assets:asset-list')
id_list = None
form = None
def get(self, request, *args, **kwargs):
assets_id = self.request.GET.get('assets_id', '')
self.assets_id_list = [int(i) for i in assets_id.split(',') if i.isdigit()]
self.id_list = [i for i in assets_id.split(',')]
if kwargs.get('form'):
self.form = kwargs['form']
elif assets_id:
self.form = self.form_class(
initial={'assets': self.assets_id_list}
initial={'assets': self.id_list}
)
else:
self.form = self.form_class()
......@@ -136,13 +138,11 @@ class AssetBulkUpdateView(AdminUserRequiredMixin, ListView):
return self.get(request, form=form, *args, **kwargs)
def get_context_data(self, **kwargs):
# assets_list = Asset.objects.filter(id__in=self.assets_id_list)
context = {
'app': 'Assets',
'action': 'Bulk update asset',
'form': self.form,
'assets_selected': self.assets_id_list,
'assets': Asset.objects.all(),
'assets_selected': self.id_list,
}
kwargs.update(context)
return super().get_context_data(**kwargs)
......@@ -270,13 +270,6 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
asset_dict = dict(zip(attr, row))
id_ = asset_dict.pop('id', 0)
try:
id_ = int(id_)
except ValueError:
id_ = 0
asset = get_object_or_none(Asset, id=id_)
for k, v in asset_dict.items():
if k == 'cluster':
v = get_object_or_none(Cluster, name=v)
......@@ -296,6 +289,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
continue
asset_dict[k] = v
asset = get_object_or_none(Asset, id=id_) if is_uuid(id_) else None
if not asset:
try:
groups = asset_dict.pop('groups')
......
# -*- coding: utf-8 -*-
#
import re
from collections import OrderedDict
from six import string_types
import base64
......@@ -29,6 +29,7 @@ from django.utils import timezone
from .compat import to_bytes, to_string
SECRET_KEY = settings.SECRET_KEY
UUID_PATTERN = re.compile(r'[0-9a-zA-Z\-]{36}')
def reverse(view_name, urlconf=None, args=None, kwargs=None,
......@@ -382,4 +383,11 @@ def get_short_uuid_str():
return str(uuid.uuid4()).split('-')[-1]
def is_uuid(s):
if UUID_PATTERN.match(s):
return True
else:
return False
signer = Signer()
......@@ -209,7 +209,7 @@ msgstr "资产组"
#: assets/models/asset.py:51 assets/models/user.py:198
#: assets/templates/assets/asset_detail.html:85 templates/_nav.html:24
msgid "Cluster"
msgstr "机房"
msgstr "集群"
#: assets/models/asset.py:52 assets/templates/assets/asset_detail.html:129
msgid "Is active"
......
......@@ -11,14 +11,6 @@ from .ansible.exceptions import AnsibleError
from .models import AdHocRunHistory, Task, AdHoc
logger = get_logger(__file__)
UUID_PATTERN = re.compile(r'[0-9a-zA-Z\-]{36}')
def is_uuid(s):
if UUID_PATTERN.match(s):
return True
else:
return False
def record_adhoc(func):
......@@ -112,47 +104,6 @@ def run_adhoc(hostname_list, pattern, tasks, name=None,
return runner.run(tasks, pattern, play_name=name)
# def create_and_run_adhoc(hostname_list, pattern, tasks, name=None,
# run_as_admin=False, run_as=None, become_info=None):
# if name is None:
# name = "Adhoc-task-{}-{}".format(
# get_short_uuid_str(),
# timezone.now().strftime("%Y-%m-%d %H:%M:%S"),
# )
# task = Task(name=name)
# task.save()
# adhoc = AdHoc(
# task=task, pattern=pattern, name=name,
# run_as_admin=run_as_admin, run_as=run_as
# )
# adhoc.hosts = hostname_list
# adhoc.tasks = tasks
# adhoc.become = become_info
# adhoc.save()
# def get_task_by_name(name):
# task = get_object_or_none(Task, name=name)
# return task
# def create_task(name, created_by=""):
# return Task.objects.create(name=name, created_by=created_by)
#
#
# def create_adhoc(task, hosts, tasks, pattern='all', options=None,
# run_as_admin=False, run_as="",
# become_info=None, created_by=""):
# adhoc = AdHoc(task=task, pattern=pattern, run_as_admin=run_as_admin,
# run_as=run_as, created_by=created_by)
# adhoc.hosts = hosts
# adhoc.tasks = tasks
# adhoc.options = options
# adhoc.become = become_info
# adhoc.save()
# return adhoc
def create_or_update_task(
task_name, hosts, tasks, pattern='all', options=None,
run_as_admin=False, run_as="", become_info=None,
......
......@@ -181,10 +181,9 @@ $(document).ready(function () {
return $(this).data('uid');
}).get();
$.map(jumpserver.users_selected, function(value, index) {
users.push(parseInt(index));
users.push(index);
$('#opt_' + index).remove();
});
console.log(users);
updateGroupMember(users)
}).on('click', '.btn-delete-user-group', function () {
var $this = $(this);
......
......@@ -19,7 +19,6 @@ from django.utils import timezone
from django.utils.translation import ugettext as _
from django.utils.decorators import method_decorator
from django.views import View
from django.views.generic import ListView
from django.views.generic.base import TemplateView
from django.views.generic.edit import (
CreateView, UpdateView, FormMixin, FormView
......@@ -33,7 +32,7 @@ from ..models import User, UserGroup
from ..utils import AdminUserRequiredMixin
from ..signals import on_user_created
from common.mixins import JSONResponseMixin
from common.utils import get_logger, get_object_or_none
from common.utils import get_logger, get_object_or_none, is_uuid
__all__ = [
'UserListView', 'UserCreateView', 'UserDetailView',
......@@ -92,16 +91,6 @@ class UserUpdateView(AdminUserRequiredMixin, UpdateView):
context_object_name = 'user_object'
success_url = reverse_lazy('users:user-list')
# def form_valid(self, form):
# username = self.object.username
# user = form.save(commit=False)
# user.username = username
# user.save()
# password = self.request.POST.get('password', '')
# if password:
# user.set_password(password)
# return super().form_valid(form)
def get_context_data(self, **kwargs):
context = {'app': _('Users'), 'action': _('Update user')}
kwargs.update(context)
......@@ -146,7 +135,6 @@ class UserBulkUpdateView(AdminUserRequiredMixin, TemplateView):
'action': 'Bulk update asset',
'form': self.form,
'users_selected': self.id_list,
'users': User.objects.all(),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
......@@ -255,9 +243,7 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
if set(row) == {''}:
continue
user_dict = dict(zip(attr, row))
print(user_dict)
id_ = user_dict.pop('id', 0)
user = get_object_or_none(User, id=id_)
id_ = user_dict.pop('id')
for k, v in user_dict.items():
if k in ['is_active']:
if v.lower() == 'false':
......@@ -271,6 +257,7 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
continue
user_dict[k] = v
user = get_object_or_none(User, id=id_) if is_uuid(id_) else None
if not user:
try:
groups = user_dict.pop('groups')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册