mirror of https://github.com/jumpserver/jumpserver
[Bugfix] 修复资产模块中一些bug
parent
a308000d2e
commit
b4e1ac1953
|
@ -74,23 +74,30 @@ class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView):
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupUpdateApi(generics.RetrieveUpdateAPIView):
|
class GroupUpdateAssetsApi(generics.RetrieveUpdateAPIView):
|
||||||
"""
|
"""
|
||||||
Asset group, update it's asset member
|
Asset group, update it's asset member
|
||||||
"""
|
"""
|
||||||
queryset = AssetGroup.objects.all()
|
queryset = AssetGroup.objects.all()
|
||||||
serializer_class = serializers.AssetGroupUpdateSerializer
|
serializer_class = serializers.GroupUpdateAssetsSerializer
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupUpdateSystemUserApi(generics.RetrieveUpdateAPIView):
|
class GroupAddAssetsApi(generics.UpdateAPIView):
|
||||||
"""
|
|
||||||
Asset group push system user
|
|
||||||
"""
|
|
||||||
queryset = AssetGroup.objects.all()
|
queryset = AssetGroup.objects.all()
|
||||||
serializer_class = serializers.AssetGroupUpdateSystemUserSerializer
|
serializer_class = serializers.GroupUpdateAssetsSerializer
|
||||||
permission_classes = (IsSuperUser,)
|
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):
|
class ClusterUpdateAssetsApi(generics.RetrieveUpdateAPIView):
|
||||||
"""
|
"""
|
||||||
|
@ -110,6 +117,24 @@ class ClusterViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
permission_classes = (IsSuperUser,)
|
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):
|
class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
"""
|
"""
|
||||||
Admin user api set, for add,delete,update,list,retrieve resource
|
Admin user api set, for add,delete,update,list,retrieve resource
|
||||||
|
@ -119,6 +144,24 @@ class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
|
||||||
|
class AdminUserAddClustersApi(generics.UpdateAPIView):
|
||||||
|
queryset = AdminUser.objects.all()
|
||||||
|
serializer_class = serializers.AdminUserUpdateClusterSerializer
|
||||||
|
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 SystemUserViewSet(IDInFilterMixin, BulkModelViewSet):
|
class SystemUserViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
"""
|
"""
|
||||||
System user api set, for add,delete,update,list,retrieve resource
|
System user api set, for add,delete,update,list,retrieve resource
|
||||||
|
@ -128,45 +171,6 @@ class SystemUserViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
permission_classes = (IsSuperUserOrAppUser,)
|
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
|
|
||||||
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,)
|
|
||||||
|
|
||||||
|
|
||||||
class SystemUserUpdateAssetGroupApi(generics.RetrieveUpdateAPIView):
|
|
||||||
"""
|
|
||||||
System user update asset group
|
|
||||||
"""
|
|
||||||
queryset = SystemUser.objects.all()
|
|
||||||
serializer_class = serializers.SystemUserUpdateAssetGroupSerializer
|
|
||||||
permission_classes = (IsSuperUser,)
|
|
||||||
|
|
||||||
|
|
||||||
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
|
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
|
||||||
"""
|
"""
|
||||||
Asset bulk update api
|
Asset bulk update api
|
||||||
|
@ -229,22 +233,3 @@ class AssetAdminUserTestView(AssetRefreshHardwareView):
|
||||||
else:
|
else:
|
||||||
return Response('0', status=502)
|
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,
|
required=True,
|
||||||
help_text='* required',
|
help_text='* required',
|
||||||
label=_('Select assets'),
|
label=_('Select assets'),
|
||||||
|
choices=[(asset.id, asset.hostname) for asset in Asset.objects.all()],
|
||||||
widget=forms.SelectMultiple(
|
widget=forms.SelectMultiple(
|
||||||
attrs={
|
attrs={
|
||||||
'class': 'select2',
|
'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:
|
class Meta:
|
||||||
model = Asset
|
model = Asset
|
||||||
|
@ -81,9 +87,16 @@ class AssetBulkUpdateForm(forms.ModelForm):
|
||||||
}
|
}
|
||||||
|
|
||||||
def save(self, commit=True):
|
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')
|
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 = Asset.objects.filter(id__in=assets_id)
|
||||||
assets.update(**cleaned_data)
|
assets.update(**cleaned_data)
|
||||||
if groups:
|
if groups:
|
||||||
|
@ -153,17 +166,18 @@ class AdminUserForm(forms.ModelForm):
|
||||||
|
|
||||||
def save(self, commit=True):
|
def save(self, commit=True):
|
||||||
# Because we define custom field, so we need rewrite :method: `save`
|
# 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']
|
password = self.cleaned_data['password']
|
||||||
private_key = self.cleaned_data['private_key_file']
|
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:
|
if private_key:
|
||||||
public_key = ssh_pubkey_gen(private_key)
|
public_key = ssh_pubkey_gen(private_key)
|
||||||
admin_user.private_key = private_key
|
|
||||||
admin_user.public_key = public_key
|
admin_user.set_auth(password=password, public_key=public_key, private_key=private_key)
|
||||||
admin_user.save()
|
|
||||||
return admin_user
|
return admin_user
|
||||||
|
|
||||||
def clean_private_key_file(self):
|
def clean_private_key_file(self):
|
||||||
|
|
|
@ -47,7 +47,7 @@ class AssetUpdateSystemUserSerializer(serializers.ModelSerializer):
|
||||||
fields = ['id', 'system_users']
|
fields = ['id', 'system_users']
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupUpdateSerializer(serializers.ModelSerializer):
|
class GroupUpdateAssetsSerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
资产组更新需要的数据结构
|
资产组更新需要的数据结构
|
||||||
"""
|
"""
|
||||||
|
@ -58,17 +58,6 @@ class AssetGroupUpdateSerializer(serializers.ModelSerializer):
|
||||||
fields = ['id', 'assets']
|
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):
|
class ClusterUpdateAssetsSerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
集群更新资产数据结构
|
集群更新资产数据结构
|
||||||
|
@ -135,6 +124,17 @@ class SystemUserSerializer(serializers.ModelSerializer):
|
||||||
return amount
|
return amount
|
||||||
|
|
||||||
|
|
||||||
|
class AdminUserUpdateClusterSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
管理用户更新关联到的集群
|
||||||
|
"""
|
||||||
|
clusters = serializers.PrimaryKeyRelatedField(many=True, queryset=Cluster.objects.all())
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = AdminUser
|
||||||
|
fields = ['id', 'clusters']
|
||||||
|
|
||||||
|
|
||||||
class AssetSystemUserSerializer(serializers.ModelSerializer):
|
class AssetSystemUserSerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
查看授权的资产系统用户的数据结构,这个和AssetSerializer不同,字段少
|
查看授权的资产系统用户的数据结构,这个和AssetSerializer不同,字段少
|
||||||
|
@ -144,28 +144,6 @@ class AssetSystemUserSerializer(serializers.ModelSerializer):
|
||||||
fields = ('id', 'name', 'username', 'priority', 'protocol', 'comment',)
|
fields = ('id', 'name', 'username', 'priority', 'protocol', 'comment',)
|
||||||
|
|
||||||
|
|
||||||
class SystemUserUpdateAssetsSerializer(serializers.ModelSerializer):
|
|
||||||
"""
|
|
||||||
系统用户更新关联资产的数据结构
|
|
||||||
"""
|
|
||||||
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = SystemUser
|
|
||||||
fields = ['id', 'assets']
|
|
||||||
|
|
||||||
|
|
||||||
class SystemUserUpdateAssetGroupSerializer(serializers.ModelSerializer):
|
|
||||||
"""
|
|
||||||
系统用户更新资产组的api
|
|
||||||
"""
|
|
||||||
asset_groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = SystemUser
|
|
||||||
fields = ['id', 'asset_groups']
|
|
||||||
|
|
||||||
|
|
||||||
class SystemUserSimpleSerializer(serializers.ModelSerializer):
|
class SystemUserSimpleSerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
系统用户最基本信息的数据结构
|
系统用户最基本信息的数据结构
|
||||||
|
|
|
@ -102,12 +102,12 @@
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Using this as cluster admin user' %}
|
<i class="fa fa-info-circle"></i> {% trans 'Using this as cluster admin user' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table group_edit" id="add-asset2group">
|
<table class="table group_edit" id="table-clusters">
|
||||||
<tbody>
|
<tbody>
|
||||||
<form>
|
<form>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" class="no-borders">
|
<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 %}
|
{% for cluster in cluster_remain %}
|
||||||
<option value="{{ cluster.id }}" id="opt_{{ cluster.id }}" >{{ cluster.name }}</option>
|
<option value="{{ cluster.id }}" id="opt_{{ cluster.id }}" >{{ cluster.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -116,17 +116,14 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" class="no-borders">
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% for cluster in admin_user.cluster_set.all %}
|
{% for cluster in admin_user.cluster_set.all %}
|
||||||
<tr>
|
<tr>
|
||||||
<td ><b class="bdg_group" data-gid={{ cluster.id }}>{{ cluster.name }}</b></td>
|
<td ><b class="bdg_cluster" 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>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -161,74 +158,48 @@ Array.prototype.unique = function(){
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
function objectRemove(obj, name, url, data) {
|
|
||||||
function doRemove() {
|
function bindToCluster(clusters) {
|
||||||
var body = data;
|
var the_url = "{% url 'api-assets:admin-user-add-clusters' pk=admin_user.id %}";
|
||||||
var success = function() {
|
var body = {
|
||||||
swal('Remove!', "[ "+name+"]"+" has been deleted ", "success");
|
clusters: clusters
|
||||||
$(obj).parent().parent().remove();
|
};
|
||||||
};
|
var success = function(data) {
|
||||||
var fail = function() {
|
// remove all the selected groups from select > option and rendered ul element;
|
||||||
swal("Failed", "Remove"+"[ "+name+" ]"+"failed", "error");
|
$('.select2-selection__rendered').empty();
|
||||||
};
|
$('#cluster_selected').val('');
|
||||||
APIUpdateAttr({
|
$.map(jumpserver.cluster_selected, function(cluster_name, index) {
|
||||||
url: url,
|
console.log(index);
|
||||||
body: JSON.stringify(body),
|
$('#opt_' + index).remove();
|
||||||
method: 'PATCH',
|
// change tr html of user groups.
|
||||||
success: success,
|
$('#table-clusters tbody').append(
|
||||||
error: fail
|
'<tr>' +
|
||||||
|
'<td><b class="bdg_cluster" data-gid="' + index + '">' + cluster_name + '</b></td>' +
|
||||||
|
'</tr>'
|
||||||
|
)
|
||||||
});
|
});
|
||||||
}
|
$.map(jumpserver.cluster_selected, function(value, index) {
|
||||||
swal({
|
$('#opt_' + index).remove();
|
||||||
title: 'Are you sure remove ?',
|
});
|
||||||
text: " [" + name + "] ",
|
// clear jumpserver.groups_selected
|
||||||
type: "warning",
|
jumpserver.cluster_selected = {};
|
||||||
showCancelButton: true,
|
};
|
||||||
cancelButtonText: 'Cancel',
|
APIUpdateAttr({
|
||||||
confirmButtonColor: "#DD6B55",
|
url: the_url,
|
||||||
confirmButtonText: 'Confirm',
|
body: JSON.stringify(body),
|
||||||
closeOnConfirm: false
|
success: success
|
||||||
}, function () {
|
|
||||||
doRemove()
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function adminUserDelete(name, url) {
|
jumpserver.cluster_selected = {};
|
||||||
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 = {};
|
|
||||||
$(document).ready(function () {
|
$(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 () {
|
.on('click', '.btn-delete-admin-user', function () {
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
|
@ -238,5 +209,15 @@ $(document).ready(function () {
|
||||||
var redirect_url = "{% url 'assets:admin-user-list' %}";
|
var redirect_url = "{% url 'assets:admin-user-list' %}";
|
||||||
objectDelete($this, name, the_url, redirect_url);
|
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>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -247,7 +247,6 @@
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
jumpserver.groups_selected = {};
|
jumpserver.groups_selected = {};
|
||||||
jumpserver.system_user_selected = {};
|
|
||||||
function updateAssetGroups(groups) {
|
function updateAssetGroups(groups) {
|
||||||
var the_url = "{% url 'api-assets:asset-update-group' pk=asset.id %}";
|
var the_url = "{% url 'api-assets:asset-update-group' pk=asset.id %}";
|
||||||
var body = {
|
var body = {
|
||||||
|
|
|
@ -94,39 +94,34 @@
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
jumpserver.assets_selected = {};
|
jumpserver.assets_selected = {};
|
||||||
function updateGroupAssets(assets) {
|
function addAssets(assets) {
|
||||||
var the_url = "{}";
|
var the_url = "{% url 'api-assets:group-add-assets' pk=asset_group.id %}";
|
||||||
var body = {
|
var body = {
|
||||||
assets: Object.assign([], assets)
|
assets: assets
|
||||||
};
|
};
|
||||||
|
|
||||||
var $data_table = $("#asset_list_table").DataTable();
|
var $data_table = $("#asset_list_table").DataTable();
|
||||||
var success = function(data) {
|
var success = function(data) {
|
||||||
$('.select2-selection__rendered').empty();
|
$('.select2-selection__rendered').empty();
|
||||||
$.map(jumpserver.assets_selected, function(asset_ip, index) {
|
$data_table.ajax.reload();
|
||||||
$('#opt_' + index).remove();
|
jumpserver.groups_selected = {};
|
||||||
$data_table.ajax.reload();
|
|
||||||
});
|
|
||||||
jumpserver.groups_selected = {};
|
|
||||||
};
|
};
|
||||||
console.log(body);
|
|
||||||
|
|
||||||
//APIUpdateAttr({
|
APIUpdateAttr({
|
||||||
// url: the_url,
|
url: the_url,
|
||||||
// body: JSON.stringify(body),
|
body: JSON.stringify(body),
|
||||||
// method: 'PUT',
|
method: 'PUT',
|
||||||
// success: success
|
success: success
|
||||||
//});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function leaveGroup(obj, name, url, data) {
|
function leaveGroup(obj, name, url, data) {
|
||||||
function doDelete() {
|
|
||||||
var body = data;
|
var body = data;
|
||||||
var success = function() {
|
var success = function() {
|
||||||
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
|
|
||||||
$(obj).parent().parent().remove();
|
$(obj).parent().parent().remove();
|
||||||
};
|
};
|
||||||
var fail = function() {
|
var fail = function() {
|
||||||
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
|
console.log("Remove failed")
|
||||||
};
|
};
|
||||||
APIUpdateAttr({
|
APIUpdateAttr({
|
||||||
url: url,
|
url: url,
|
||||||
|
@ -135,19 +130,6 @@ function leaveGroup(obj, name, url, data) {
|
||||||
success: success,
|
success: success,
|
||||||
error: fail
|
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) {
|
Array.prototype.remove = function(val) {
|
||||||
|
@ -188,13 +170,13 @@ function initTable() {
|
||||||
}},
|
}},
|
||||||
{targets: 5, createdCell: function (td, cellData, rowData) {
|
{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 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)
|
$(td).html(update_btn + del_btn)
|
||||||
}}
|
}}
|
||||||
],
|
],
|
||||||
ajax_url: '{% url "api-assets:asset-list" %}?asset_group_id={{ asset_group.id }}',
|
ajax_url: '{% url "api-assets:asset-list" %}?asset_group_id={{ asset_group.id }}',
|
||||||
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
|
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()
|
op_html: $('#actions').html()
|
||||||
};
|
};
|
||||||
jumpserver.initDataTable(options);
|
jumpserver.initDataTable(options);
|
||||||
|
@ -208,7 +190,6 @@ $(document).ready(function () {
|
||||||
.on('select2:select', function(evt) {
|
.on('select2:select', function(evt) {
|
||||||
var data = evt.params.data;
|
var data = evt.params.data;
|
||||||
jumpserver.assets_selected[data.id] = data.text;
|
jumpserver.assets_selected[data.id] = data.text;
|
||||||
console.log(jumpserver.assets_selected)
|
|
||||||
})
|
})
|
||||||
.on('select2:unselect', function(evt) {
|
.on('select2:unselect', function(evt) {
|
||||||
var data = evt.params.data;
|
var data = evt.params.data;
|
||||||
|
@ -223,22 +204,26 @@ $(document).ready(function () {
|
||||||
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
||||||
return false;
|
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 () {
|
.on('click', '.btn-leave-group', function () {
|
||||||
var $this = $(this);
|
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 name = $(this).closest("tr").find(":nth-child(1) > a").html();
|
||||||
var assets = [];
|
var assets = [];
|
||||||
$('#asset_list_table > tbody > tr').map(function () {
|
$('#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');
|
var delete_asset_id = $(this).data('aid');
|
||||||
assets.remove(delete_asset_id);
|
assets.remove(delete_asset_id);
|
||||||
|
console.log(assets);
|
||||||
var data = {"assets": assets};
|
var data = {"assets": assets};
|
||||||
leaveGroup($this, name, the_url, data);
|
leaveGroup($this, name, the_url, data);
|
||||||
})
|
})
|
||||||
|
|
|
@ -21,19 +21,6 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</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' %}
|
{% include 'assets/_asset_group_bulk_update_modal.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content_bottom_left %}{% endblock %}
|
{% block content_bottom_left %}{% endblock %}
|
||||||
|
|
|
@ -45,17 +45,15 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ibox-content">
|
<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>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-center">
|
|
||||||
<input type="checkbox" id="check_all" class="ipt_check_all" >
|
|
||||||
</th>
|
|
||||||
<th>{% trans 'Hostname' %}</th>
|
<th>{% trans 'Hostname' %}</th>
|
||||||
<th>{% trans 'IP' %}</th>
|
<th>{% trans 'IP' %}</th>
|
||||||
<th>{% trans 'Port' %}</th>
|
<th>{% trans 'Port' %}</th>
|
||||||
<th>{% trans 'Type' %}</th>
|
<th>{% trans 'Type' %}</th>
|
||||||
<th>{% trans 'Valid' %}</th>
|
<th>{% trans 'Alive' %}</th>
|
||||||
|
<th>{% trans 'Action' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -84,7 +82,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
<td colspan="2">
|
<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>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</form>
|
</form>
|
||||||
|
@ -112,18 +110,15 @@ Array.prototype.remove = function(val) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateClusterAssets(assets) {
|
function addAssets(assets) {
|
||||||
var the_url = "{% url 'api-assets:cluster-update-assets' pk=cluster.id %}";
|
var the_url = "{% url 'api-assets:cluster-add-assets' pk=cluster.id %}";
|
||||||
var body = {
|
var body = {
|
||||||
assets: Object.assign([], assets)
|
assets: assets
|
||||||
};
|
};
|
||||||
var $data_table = $("#cluster_assets_table").DataTable();
|
var $data_table = $("#cluster_assets_table").DataTable();
|
||||||
var success = function(data) {
|
var success = function(data) {
|
||||||
$('.select2-selection__rendered').empty();
|
$('.select2-selection__rendered').empty();
|
||||||
$.map(jumpserver.assets_selected, function(asset_ip, index) {
|
$data_table.ajax.reload();
|
||||||
$('#opt_' + index).remove();
|
|
||||||
$data_table.ajax.reload();
|
|
||||||
});
|
|
||||||
jumpserver.groups_selected = {};
|
jumpserver.groups_selected = {};
|
||||||
};
|
};
|
||||||
APIUpdateAttr({
|
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() {
|
function initTable() {
|
||||||
var options = {
|
var options = {
|
||||||
|
@ -157,23 +136,29 @@ function initTable() {
|
||||||
buttons: [],
|
buttons: [],
|
||||||
order: [],
|
order: [],
|
||||||
columnDefs: [
|
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>';
|
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));
|
$(td).html(detail_btn.replace('{{ DEFAULT_PK }}', rowData.id));
|
||||||
}},
|
}},
|
||||||
{targets: 5, createdCell: function (td, cellData) {
|
{targets: 4, createdCell: function (td, cellData) {
|
||||||
if (!cellData) {
|
if (!cellData) {
|
||||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||||
} else {
|
} else {
|
||||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
$(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 }}',
|
ajax_url: '{% url "api-assets:asset-list" %}?cluster_id={{ cluster.id }}',
|
||||||
columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" },
|
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
|
||||||
{data: "type" }, {data: "is_active" }],
|
{data: "get_type_display" }, {data: "is_connective" }, {data: "id"}],
|
||||||
op_html: $('#actions').html()
|
op_html: $('#actions').html()
|
||||||
};
|
};
|
||||||
jumpserver.initDataTable(options);
|
jumpserver.initDataTable(options);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
@ -189,166 +174,16 @@ $(document).ready(function () {
|
||||||
initTable();
|
initTable();
|
||||||
})
|
})
|
||||||
|
|
||||||
.on('click', '.btn-asset-attach', function () {
|
.on('click', '.btn-add-assets', function () {
|
||||||
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
var assets=[];
|
var assets_id = [];
|
||||||
var $data_table = $("#cluster_assets_table").DataTable();
|
$.map(jumpserver.assets_selected, function(value, index) {
|
||||||
$.ajax({
|
assets_id.push(index);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
addAssets(assets_id);
|
||||||
});
|
|
||||||
})
|
})
|
||||||
|
|
||||||
.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);
|
|
||||||
});
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
.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>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -27,18 +27,6 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</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 %}
|
{% endblock %}
|
||||||
{% block content_bottom_left %}{% endblock %}
|
{% block content_bottom_left %}{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
|
|
|
@ -19,37 +19,22 @@ urlpatterns = [
|
||||||
name='system-user-auth-info'),
|
name='system-user-auth-info'),
|
||||||
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/groups/$',
|
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/groups/$',
|
||||||
api.AssetUpdateGroupApi.as_view(), name='asset-update-group'),
|
api.AssetUpdateGroupApi.as_view(), name='asset-update-group'),
|
||||||
|
|
||||||
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/refresh/$',
|
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/refresh/$',
|
||||||
api.AssetRefreshHardwareView.as_view(), name='asset-refresh'),
|
api.AssetRefreshHardwareView.as_view(), name='asset-refresh'),
|
||||||
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/admin-user-test/$',
|
url(r'^v1/assets/(?P<pk>[0-9a-zA-Z\-]{36})/admin-user-test/$',
|
||||||
api.AssetAdminUserTestView.as_view(), name='asset-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
|
# 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/$',
|
url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$',
|
||||||
api.AssetGroupUpdateApi.as_view(), name='asset-groups-update'),
|
api.GroupUpdateAssetsApi.as_view(), name='group-update-assets'),
|
||||||
|
url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$',
|
||||||
# update the asset group, and add or delete the system_user to the group
|
api.GroupAddAssetsApi.as_view(), name='group-add-assets'),
|
||||||
url(r'^v1/groups/(?P<pk>[0-9a-zA-Z\-]{36})/system-users/$',
|
|
||||||
api.AssetGroupUpdateSystemUserApi.as_view(), name='asset-groups-update-systemusers'),
|
|
||||||
|
|
||||||
# update the Cluster, and add or delete the assets to the Cluster
|
# update the Cluster, and add or delete the assets to the Cluster
|
||||||
url(r'^v1/cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$',
|
url(r'^v1/cluster/(?P<pk>[0-9a-zA-Z\-]{36})/assets/$',
|
||||||
api.ClusterUpdateAssetsApi.as_view(), name='cluster-update-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
|
urlpatterns += router.urls
|
||||||
|
|
|
@ -24,7 +24,7 @@ from django.shortcuts import redirect
|
||||||
|
|
||||||
|
|
||||||
from common.mixins import JSONResponseMixin
|
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 .. import forms
|
||||||
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
|
from ..models import Asset, AssetGroup, AdminUser, Cluster, SystemUser
|
||||||
from ..hands import AdminUserRequiredMixin
|
from ..hands import AdminUserRequiredMixin
|
||||||
|
@ -112,16 +112,18 @@ class AssetBulkUpdateView(AdminUserRequiredMixin, ListView):
|
||||||
form_class = forms.AssetBulkUpdateForm
|
form_class = forms.AssetBulkUpdateForm
|
||||||
template_name = 'assets/asset_bulk_update.html'
|
template_name = 'assets/asset_bulk_update.html'
|
||||||
success_url = reverse_lazy('assets:asset-list')
|
success_url = reverse_lazy('assets:asset-list')
|
||||||
|
id_list = None
|
||||||
|
form = None
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
assets_id = self.request.GET.get('assets_id', '')
|
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'):
|
if kwargs.get('form'):
|
||||||
self.form = kwargs['form']
|
self.form = kwargs['form']
|
||||||
elif assets_id:
|
elif assets_id:
|
||||||
self.form = self.form_class(
|
self.form = self.form_class(
|
||||||
initial={'assets': self.assets_id_list}
|
initial={'assets': self.id_list}
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.form = self.form_class()
|
self.form = self.form_class()
|
||||||
|
@ -136,13 +138,11 @@ class AssetBulkUpdateView(AdminUserRequiredMixin, ListView):
|
||||||
return self.get(request, form=form, *args, **kwargs)
|
return self.get(request, form=form, *args, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
# assets_list = Asset.objects.filter(id__in=self.assets_id_list)
|
|
||||||
context = {
|
context = {
|
||||||
'app': 'Assets',
|
'app': 'Assets',
|
||||||
'action': 'Bulk update asset',
|
'action': 'Bulk update asset',
|
||||||
'form': self.form,
|
'form': self.form,
|
||||||
'assets_selected': self.assets_id_list,
|
'assets_selected': self.id_list,
|
||||||
'assets': Asset.objects.all(),
|
|
||||||
}
|
}
|
||||||
kwargs.update(context)
|
kwargs.update(context)
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
@ -270,13 +270,6 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
|
||||||
|
|
||||||
asset_dict = dict(zip(attr, row))
|
asset_dict = dict(zip(attr, row))
|
||||||
id_ = asset_dict.pop('id', 0)
|
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():
|
for k, v in asset_dict.items():
|
||||||
if k == 'cluster':
|
if k == 'cluster':
|
||||||
v = get_object_or_none(Cluster, name=v)
|
v = get_object_or_none(Cluster, name=v)
|
||||||
|
@ -296,6 +289,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
|
||||||
continue
|
continue
|
||||||
asset_dict[k] = v
|
asset_dict[k] = v
|
||||||
|
|
||||||
|
asset = get_object_or_none(Asset, id=id_) if is_uuid(id_) else None
|
||||||
if not asset:
|
if not asset:
|
||||||
try:
|
try:
|
||||||
groups = asset_dict.pop('groups')
|
groups = asset_dict.pop('groups')
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
import re
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from six import string_types
|
from six import string_types
|
||||||
import base64
|
import base64
|
||||||
|
@ -29,6 +29,7 @@ from django.utils import timezone
|
||||||
from .compat import to_bytes, to_string
|
from .compat import to_bytes, to_string
|
||||||
|
|
||||||
SECRET_KEY = settings.SECRET_KEY
|
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,
|
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]
|
return str(uuid.uuid4()).split('-')[-1]
|
||||||
|
|
||||||
|
|
||||||
|
def is_uuid(s):
|
||||||
|
if UUID_PATTERN.match(s):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
signer = Signer()
|
signer = Signer()
|
||||||
|
|
Binary file not shown.
|
@ -209,7 +209,7 @@ msgstr "资产组"
|
||||||
#: assets/models/asset.py:51 assets/models/user.py:198
|
#: assets/models/asset.py:51 assets/models/user.py:198
|
||||||
#: assets/templates/assets/asset_detail.html:85 templates/_nav.html:24
|
#: assets/templates/assets/asset_detail.html:85 templates/_nav.html:24
|
||||||
msgid "Cluster"
|
msgid "Cluster"
|
||||||
msgstr "机房"
|
msgstr "集群"
|
||||||
|
|
||||||
#: assets/models/asset.py:52 assets/templates/assets/asset_detail.html:129
|
#: assets/models/asset.py:52 assets/templates/assets/asset_detail.html:129
|
||||||
msgid "Is active"
|
msgid "Is active"
|
||||||
|
|
|
@ -11,14 +11,6 @@ from .ansible.exceptions import AnsibleError
|
||||||
from .models import AdHocRunHistory, Task, AdHoc
|
from .models import AdHocRunHistory, Task, AdHoc
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
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):
|
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)
|
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(
|
def create_or_update_task(
|
||||||
task_name, hosts, tasks, pattern='all', options=None,
|
task_name, hosts, tasks, pattern='all', options=None,
|
||||||
run_as_admin=False, run_as="", become_info=None,
|
run_as_admin=False, run_as="", become_info=None,
|
||||||
|
|
|
@ -181,10 +181,9 @@ $(document).ready(function () {
|
||||||
return $(this).data('uid');
|
return $(this).data('uid');
|
||||||
}).get();
|
}).get();
|
||||||
$.map(jumpserver.users_selected, function(value, index) {
|
$.map(jumpserver.users_selected, function(value, index) {
|
||||||
users.push(parseInt(index));
|
users.push(index);
|
||||||
$('#opt_' + index).remove();
|
$('#opt_' + index).remove();
|
||||||
});
|
});
|
||||||
console.log(users);
|
|
||||||
updateGroupMember(users)
|
updateGroupMember(users)
|
||||||
}).on('click', '.btn-delete-user-group', function () {
|
}).on('click', '.btn-delete-user-group', function () {
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
|
|
|
@ -19,7 +19,6 @@ from django.utils import timezone
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.views import View
|
from django.views import View
|
||||||
from django.views.generic import ListView
|
|
||||||
from django.views.generic.base import TemplateView
|
from django.views.generic.base import TemplateView
|
||||||
from django.views.generic.edit import (
|
from django.views.generic.edit import (
|
||||||
CreateView, UpdateView, FormMixin, FormView
|
CreateView, UpdateView, FormMixin, FormView
|
||||||
|
@ -33,7 +32,7 @@ from ..models import User, UserGroup
|
||||||
from ..utils import AdminUserRequiredMixin
|
from ..utils import AdminUserRequiredMixin
|
||||||
from ..signals import on_user_created
|
from ..signals import on_user_created
|
||||||
from common.mixins import JSONResponseMixin
|
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__ = [
|
__all__ = [
|
||||||
'UserListView', 'UserCreateView', 'UserDetailView',
|
'UserListView', 'UserCreateView', 'UserDetailView',
|
||||||
|
@ -92,16 +91,6 @@ class UserUpdateView(AdminUserRequiredMixin, UpdateView):
|
||||||
context_object_name = 'user_object'
|
context_object_name = 'user_object'
|
||||||
success_url = reverse_lazy('users:user-list')
|
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):
|
def get_context_data(self, **kwargs):
|
||||||
context = {'app': _('Users'), 'action': _('Update user')}
|
context = {'app': _('Users'), 'action': _('Update user')}
|
||||||
kwargs.update(context)
|
kwargs.update(context)
|
||||||
|
@ -146,7 +135,6 @@ class UserBulkUpdateView(AdminUserRequiredMixin, TemplateView):
|
||||||
'action': 'Bulk update asset',
|
'action': 'Bulk update asset',
|
||||||
'form': self.form,
|
'form': self.form,
|
||||||
'users_selected': self.id_list,
|
'users_selected': self.id_list,
|
||||||
'users': User.objects.all(),
|
|
||||||
}
|
}
|
||||||
kwargs.update(context)
|
kwargs.update(context)
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
@ -255,9 +243,7 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
|
||||||
if set(row) == {''}:
|
if set(row) == {''}:
|
||||||
continue
|
continue
|
||||||
user_dict = dict(zip(attr, row))
|
user_dict = dict(zip(attr, row))
|
||||||
print(user_dict)
|
id_ = user_dict.pop('id')
|
||||||
id_ = user_dict.pop('id', 0)
|
|
||||||
user = get_object_or_none(User, id=id_)
|
|
||||||
for k, v in user_dict.items():
|
for k, v in user_dict.items():
|
||||||
if k in ['is_active']:
|
if k in ['is_active']:
|
||||||
if v.lower() == 'false':
|
if v.lower() == 'false':
|
||||||
|
@ -271,6 +257,7 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
|
||||||
continue
|
continue
|
||||||
user_dict[k] = v
|
user_dict[k] = v
|
||||||
|
|
||||||
|
user = get_object_or_none(User, id=id_) if is_uuid(id_) else None
|
||||||
if not user:
|
if not user:
|
||||||
try:
|
try:
|
||||||
groups = user_dict.pop('groups')
|
groups = user_dict.pop('groups')
|
||||||
|
|
Loading…
Reference in New Issue