mirror of https://github.com/jumpserver/jumpserver
资产相关API及Web
parent
4c06257070
commit
dbdb8a58fe
|
@ -3,66 +3,106 @@
|
||||||
from rest_framework import viewsets, generics, mixins
|
from rest_framework import viewsets, generics, mixins
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
from rest_framework_bulk import BulkModelViewSet, BulkDestroyAPIView
|
||||||
|
from django_filters.rest_framework import DjangoFilterBackend
|
||||||
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin, ListBulkCreateUpdateDestroyAPIView
|
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin, ListBulkCreateUpdateDestroyAPIView
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
from common.mixins import IDInFilterMixin
|
from common.mixins import IDInFilterMixin
|
||||||
from common.utils import get_object_or_none, signer
|
from common.utils import get_object_or_none, signer
|
||||||
from .hands import IsSuperUserOrTerminalUser, IsSuperUser
|
from .hands import IsSuperUserOrTerminalUser, IsSuperUser
|
||||||
from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser
|
from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser, Tag
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
|
|
||||||
class AssetViewSet(IDInFilterMixin, viewsets.ModelViewSet):
|
class AssetViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
"""API endpoint that allows Asset to be viewed or edited."""
|
"""API endpoint that allows Asset to be viewed or edited."""
|
||||||
queryset = Asset.objects.all()
|
queryset = Asset.objects.all()
|
||||||
serializer_class = serializers.AssetSerializer
|
serializer_class = serializers.AssetSerializer
|
||||||
filter_fields = ('id', 'ip', 'hostname')
|
filter_backends = (DjangoFilterBackend,)
|
||||||
|
filter_fields = ('id', 'ip', 'hostname')
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = super(AssetViewSet, self).get_queryset()
|
queryset = super(AssetViewSet, self).get_queryset()
|
||||||
idc_id = self.request.query_params.get('idc_id', '')
|
idc_id = self.request.query_params.get('idc_id', '')
|
||||||
asset_group_id = self.request.query_params.get('asset_group_id', '')
|
tags_id = self.request.query_params.get('tag_id', '')
|
||||||
if idc_id:
|
system_users_id = self.request.query_params.get('system_user_id', '')
|
||||||
queryset = queryset.filter(idc__id=idc_id)
|
asset_group_id = self.request.query_params.get('asset_group_id', '')
|
||||||
|
admin_user_id = self.request.query_params.get('admin_user_id', '')
|
||||||
if asset_group_id:
|
if idc_id:
|
||||||
queryset = queryset.filter(groups__id=asset_group_id)
|
queryset = queryset.filter(idc__id=idc_id)
|
||||||
return queryset
|
if tags_id:
|
||||||
|
queryset = queryset.filter(tags__id=tags_id)
|
||||||
|
if system_users_id:
|
||||||
|
queryset = queryset.filter(system_users__id=system_users_id)
|
||||||
|
if admin_user_id:
|
||||||
|
queryset = queryset.filter(admin_user__id=admin_user_id)
|
||||||
|
if asset_group_id:
|
||||||
|
queryset = queryset.filter(groups__id=asset_group_id)
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupViewSet(viewsets.ModelViewSet):
|
class AssetGroupViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
""" API endpoint that allows AssetGroup to be viewed or edited.
|
queryset = AssetGroup.objects.all()
|
||||||
some other comment
|
serializer_class = serializers.AssetGroupSerializer
|
||||||
"""
|
permission_classes = (IsSuperUser,)
|
||||||
queryset = AssetGroup.objects.all()
|
|
||||||
serializer_class = serializers.AssetGroupSerializer
|
|
||||||
|
|
||||||
class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView):
|
class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView):
|
||||||
queryset = Asset.objects.all()
|
queryset = Asset.objects.all()
|
||||||
serializer_class = serializers.AssetUpdateGroupSerializer
|
serializer_class = serializers.AssetUpdateGroupSerializer
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
class IDCViewSet(viewsets.ModelViewSet):
|
## update the asset group, and add or delete the asset to the group
|
||||||
"""API endpoint that allows IDC to be viewed or edited."""
|
class AssetGroupUpdateApi(generics.RetrieveUpdateAPIView):
|
||||||
queryset = IDC.objects.all()
|
queryset = AssetGroup.objects.all()
|
||||||
serializer_class = serializers.IDCSerializer
|
serializer_class = serializers.AssetGroupUpdateSerializer
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
class AdminUserViewSet(viewsets.ModelViewSet):
|
## update the asset group, and add or delete the system_user to the group
|
||||||
queryset = AdminUser.objects.all()
|
class AssetGroupUpdateSystemUserApi(generics.RetrieveUpdateAPIView):
|
||||||
serializer_class = serializers.AdminUserSerializer
|
queryset = AssetGroup.objects.all()
|
||||||
permission_classes = (IsSuperUser,)
|
serializer_class = serializers.AssetGroupUpdateSystemUserSerializer
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
## update the IDC, and add or delete the assets to the IDC
|
||||||
|
class IDCupdateAssetsApi(generics.RetrieveUpdateAPIView):
|
||||||
|
queryset = IDC.objects.all()
|
||||||
|
serializer_class = serializers.IDCUpdateAssetsSerializer
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
class IDCViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
|
"""API endpoint that allows IDC to be viewed or edited."""
|
||||||
|
queryset = IDC.objects.all()
|
||||||
|
serializer_class = serializers.IDCSerializer
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
|
queryset = AdminUser.objects.all()
|
||||||
|
serializer_class = serializers.AdminUserSerializer
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
|
||||||
|
class SystemUserViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
|
queryset = SystemUser.objects.all()
|
||||||
|
serializer_class = serializers.SystemUserSerializer
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
class SystemUserViewSet(viewsets.ModelViewSet):
|
|
||||||
queryset = SystemUser.objects.all()
|
|
||||||
serializer_class = serializers.SystemUserSerializer
|
|
||||||
permission_classes = (IsSuperUser,)
|
|
||||||
|
|
||||||
class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
|
class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
|
||||||
queryset = Asset.objects.all()
|
queryset = Asset.objects.all()
|
||||||
serializer_class = serializers.AssetUpdateSystemUserSerializer
|
serializer_class = serializers.AssetUpdateSystemUserSerializer
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
class SystemUserUpdateAssetsApi(generics.RetrieveUpdateAPIView):
|
||||||
|
queryset = SystemUser.objects.all()
|
||||||
|
serializer_class = serializers.SystemUserUpdateAssetsSerializer
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
class SystemUserUpdateAssetGroupApi(generics.RetrieveUpdateAPIView):
|
||||||
|
queryset = SystemUser.objects.all()
|
||||||
|
serializer_class = serializers.SystemUserUpdateAssetGroupSerializer
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
|
||||||
# class IDCAssetsApi(generics.ListAPIView):
|
# class IDCAssetsApi(generics.ListAPIView):
|
||||||
|
@ -79,39 +119,50 @@ class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
|
||||||
|
|
||||||
|
|
||||||
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
|
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
|
||||||
queryset = Asset.objects.all()
|
queryset = Asset.objects.all()
|
||||||
serializer_class = serializers.AssetSerializer
|
serializer_class = serializers.AssetSerializer
|
||||||
permission_classes = (IsSuperUser,)
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
|
||||||
class SystemUserAuthApi(APIView):
|
class SystemUserAuthApi(APIView):
|
||||||
permission_classes = (IsSuperUserOrTerminalUser,)
|
permission_classes = (IsSuperUserOrTerminalUser,)
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
system_user_id = request.query_params.get('system_user_id', -1)
|
system_user_id = request.query_params.get('system_user_id', -1)
|
||||||
system_user_username = request.query_params.get('system_user_username', '')
|
system_user_username = request.query_params.get('system_user_username', '')
|
||||||
|
|
||||||
system_user = get_object_or_none(SystemUser, id=system_user_id, username=system_user_username)
|
system_user = get_object_or_none(SystemUser, id=system_user_id, username=system_user_username)
|
||||||
|
|
||||||
if system_user:
|
if system_user:
|
||||||
if system_user.password:
|
if system_user.password:
|
||||||
password = signer.sign(system_user.password)
|
password = signer.sign(system_user.password)
|
||||||
else:
|
else:
|
||||||
password = signer.sign('')
|
password = signer.sign('')
|
||||||
|
|
||||||
if system_user.private_key:
|
if system_user.private_key:
|
||||||
private_key = signer.sign(system_user.private_key)
|
private_key = signer.sign(system_user.private_key)
|
||||||
else:
|
else:
|
||||||
private_key = signer.sign(None)
|
private_key = signer.sign(None)
|
||||||
|
|
||||||
response = {
|
response = {
|
||||||
'id': system_user.id,
|
'id': system_user.id,
|
||||||
'password': password,
|
'password': password,
|
||||||
'private_key': private_key,
|
'private_key': private_key,
|
||||||
}
|
}
|
||||||
|
|
||||||
return Response(response)
|
return Response(response)
|
||||||
else:
|
else:
|
||||||
return Response({'msg': 'error system user id or username'}, status=401)
|
return Response({'msg': 'error system user id or username'}, status=401)
|
||||||
|
|
||||||
|
|
||||||
|
class TagViewSet(IDInFilterMixin, BulkModelViewSet):
|
||||||
|
queryset = Tag.objects.all()
|
||||||
|
serializer_class = serializers.TagSerializer
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
## update the IDC, and add or delete the assets to the IDC
|
||||||
|
class TagUpdateAssetsApi(generics.RetrieveUpdateAPIView):
|
||||||
|
queryset = Tag.objects.all()
|
||||||
|
serializer_class = serializers.TagUpdateAssetsSerializer
|
||||||
|
permission_classes = (IsSuperUser,)
|
||||||
|
|
||||||
|
|
|
@ -20,297 +20,305 @@ from common.utils import validate_ssh_private_key, ssh_pubkey_gen
|
||||||
# 'groups': forms.SelectMultiple(attrs={'class': 'select2-groups', 'data-placeholder': _('Select asset groups')}),
|
# 'groups': forms.SelectMultiple(attrs={'class': 'select2-groups', 'data-placeholder': _('Select asset groups')}),
|
||||||
# 'system_user': forms.SelectMultiple(attrs={'class': 'select2-system-user', 'data-placeholder': _('Select asset system user')}),
|
# 'system_user': forms.SelectMultiple(attrs={'class': 'select2-system-user', 'data-placeholder': _('Select asset system user')}),
|
||||||
# 'admin_user': forms.SelectMultiple(attrs={'class': 'select2-admin-user', 'data-placeholder': _('Select asset admin user')}),
|
# 'admin_user': forms.SelectMultiple(attrs={'class': 'select2-admin-user', 'data-placeholder': _('Select asset admin user')}),
|
||||||
# }
|
# }
|
||||||
#
|
#
|
||||||
|
|
||||||
class AssetCreateForm(forms.ModelForm):
|
class AssetCreateForm(forms.ModelForm):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
instance = kwargs.get('instance', None)
|
instance = kwargs.get('instance', None)
|
||||||
if instance:
|
if instance:
|
||||||
initial = kwargs.get('initial', {})
|
initial = kwargs.get('initial', {})
|
||||||
initial['tags'] = [t.pk for t in kwargs['instance'].tags.all()]
|
initial['tags'] = [t.pk for t in kwargs['instance'].tags.all()]
|
||||||
super(AssetCreateForm, self).__init__(*args, **kwargs)
|
super(AssetCreateForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def _save_m2m(self):
|
def _save_m2m(self):
|
||||||
super(AssetCreateForm, self)._save_m2m()
|
super(AssetCreateForm, self)._save_m2m()
|
||||||
tags = self.cleaned_data['tags']
|
tags = self.cleaned_data['tags']
|
||||||
self.instance.tags.clear()
|
self.instance.tags.clear()
|
||||||
self.instance.tags.add(*tuple(tags))
|
self.instance.tags.add(*tuple(tags))
|
||||||
|
|
||||||
class Meta:
|
def clean(self):
|
||||||
model = Asset
|
clean_data = super(AssetCreateForm, self).clean()
|
||||||
tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all())
|
ip = clean_data.get('ip')
|
||||||
fields = [
|
port = clean_data.get('port')
|
||||||
'hostname', 'ip', 'port', 'type', 'comment', 'admin_user', 'system_users', 'idc', 'groups',
|
query = Asset.objects.filter(ip=ip, port=port)
|
||||||
'other_ip', 'remote_card_ip', 'mac_address', 'brand', 'cpu', 'memory', 'disk', 'os', 'cabinet_no',
|
if query:
|
||||||
'cabinet_pos', 'number', 'status', 'env', 'sn', 'tags',
|
raise forms.ValidationError('this asset has exists.')
|
||||||
]
|
|
||||||
widgets = {
|
class Meta:
|
||||||
'groups': forms.SelectMultiple(attrs={'class': 'select2',
|
model = Asset
|
||||||
'data-placeholder': _('Select asset groups')}),
|
tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all())
|
||||||
'tags': forms.SelectMultiple(attrs={'class': 'select2',
|
fields = [
|
||||||
'data-placeholder': _('Select asset tags')}),
|
'hostname', 'ip', 'port', 'type', 'comment', 'admin_user', 'system_users', 'idc', 'groups',
|
||||||
'system_users': forms.SelectMultiple(attrs={'class': 'select2',
|
'other_ip', 'remote_card_ip', 'mac_address', 'brand', 'cpu', 'memory', 'disk', 'os', 'cabinet_no',
|
||||||
'data-placeholder': _('Select asset system users')}),
|
'cabinet_pos', 'number', 'status', 'env', 'sn', 'tags',
|
||||||
'admin_user': forms.Select(attrs={'class': 'select2', 'data-placeholder': _('Select asset admin user')}),
|
]
|
||||||
}
|
widgets = {
|
||||||
help_texts = {
|
'groups': forms.SelectMultiple(attrs={'class': 'select2',
|
||||||
'hostname': '* required',
|
'data-placeholder': _('Select asset groups')}),
|
||||||
'ip': '* required',
|
'tags': forms.SelectMultiple(attrs={'class': 'select2',
|
||||||
'system_users': _('System user will be granted for user to login assets (using ansible create automatic)'),
|
'data-placeholder': _('Select asset tags')}),
|
||||||
'admin_user': _('Admin user should be exist on asset already, And have sudo ALL permission'),
|
'system_users': forms.SelectMultiple(attrs={'class': 'select2',
|
||||||
'tags': '最多5个标签,单个标签最长8个汉字,按回车确认'
|
'data-placeholder': _('Select asset system users')}),
|
||||||
}
|
'admin_user': forms.Select(attrs={'class': 'select2', 'data-placeholder': _('Select asset admin user')}),
|
||||||
|
}
|
||||||
|
help_texts = {
|
||||||
|
'hostname': '* required',
|
||||||
|
'ip': '* required',
|
||||||
|
'system_users': _('System user will be granted for user to login assets (using ansible create automatic)'),
|
||||||
|
'admin_user': _('Admin user should be exist on asset already, And have sudo ALL permission'),
|
||||||
|
'tags': '最多5个标签,单个标签最长8个汉字,按回车确认'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupForm(forms.ModelForm):
|
class AssetGroupForm(forms.ModelForm):
|
||||||
# See AdminUserForm comment same it
|
# See AdminUserForm comment same it
|
||||||
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
||||||
label=_('Asset'),
|
label=_('Asset'),
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.SelectMultiple(
|
widget=forms.SelectMultiple(
|
||||||
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
if kwargs.get('instance', None):
|
if kwargs.get('instance', None):
|
||||||
initial = kwargs.get('initial', {})
|
initial = kwargs.get('initial', {})
|
||||||
initial['assets'] = kwargs['instance'].assets.all()
|
initial['assets'] = kwargs['instance'].assets.all()
|
||||||
super(AssetGroupForm, self).__init__(*args, **kwargs)
|
super(AssetGroupForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def _save_m2m(self):
|
def _save_m2m(self):
|
||||||
super(AssetGroupForm, self)._save_m2m()
|
super(AssetGroupForm, self)._save_m2m()
|
||||||
assets = self.cleaned_data['assets']
|
assets = self.cleaned_data['assets']
|
||||||
self.instance.assets.clear()
|
self.instance.assets.clear()
|
||||||
self.instance.assets.add(*tuple(assets))
|
self.instance.assets.add(*tuple(assets))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AssetGroup
|
model = AssetGroup
|
||||||
fields = [
|
fields = [
|
||||||
"name", "comment","system_users",
|
"name", "comment","system_users",
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'name' : forms.TextInput(attrs={}),
|
'name' : forms.TextInput(attrs={}),
|
||||||
'system_users': forms.SelectMultiple(attrs={'class': 'select2-system-user', 'data-placeholder': _('Select asset system user')}),
|
'system_users': forms.SelectMultiple(attrs={'class': 'select2-system-user', 'data-placeholder': _('Select asset system user')}),
|
||||||
|
|
||||||
}
|
}
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'name': '* required',
|
'name': '* required',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class IDCForm(forms.ModelForm):
|
class IDCForm(forms.ModelForm):
|
||||||
# See AdminUserForm comment same it
|
# See AdminUserForm comment same it
|
||||||
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
||||||
label=_('Asset'),
|
label=_('Asset'),
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.SelectMultiple(
|
widget=forms.SelectMultiple(
|
||||||
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
if kwargs.get('instance'):
|
if kwargs.get('instance'):
|
||||||
initial = kwargs.get('initial', {})
|
initial = kwargs.get('initial', {})
|
||||||
initial['assets'] = kwargs['instance'].assets.all()
|
initial['assets'] = kwargs['instance'].assets.all()
|
||||||
super(IDCForm, self).__init__(*args, **kwargs)
|
super(IDCForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def _save_m2m(self):
|
def _save_m2m(self):
|
||||||
super(IDCForm, self)._save_m2m()
|
super(IDCForm, self)._save_m2m()
|
||||||
assets = self.cleaned_data['assets']
|
assets = self.cleaned_data['assets']
|
||||||
self.instance.assets.clear()
|
self.instance.assets.clear()
|
||||||
self.instance.assets.add(*tuple(assets))
|
self.instance.assets.add(*tuple(assets))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IDC
|
model = IDC
|
||||||
fields = ['name', "bandwidth", "operator", 'contact', 'phone', 'address', 'intranet', 'extranet','comment']
|
fields = ['name', "bandwidth", "operator", 'contact', 'phone', 'address', 'intranet', 'extranet','comment']
|
||||||
widgets = {
|
widgets = {
|
||||||
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
|
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
|
||||||
'intranet': forms.Textarea(
|
'intranet': forms.Textarea(
|
||||||
attrs={'placeholder': 'IP段之间用逗号隔开,如:192.168.1.0/24,192.168.1.0/24'}),
|
attrs={'placeholder': 'IP段之间用逗号隔开,如:192.168.1.0/24,192.168.1.0/24'}),
|
||||||
'extranet': forms.Textarea(
|
'extranet': forms.Textarea(
|
||||||
attrs={'placeholder': 'IP段之间用逗号隔开,如:201.1.32.1/24,202.2.32.1/24'})
|
attrs={'placeholder': 'IP段之间用逗号隔开,如:201.1.32.1/24,202.2.32.1/24'})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AdminUserForm(forms.ModelForm):
|
class AdminUserForm(forms.ModelForm):
|
||||||
# Admin user assets define, let user select, save it in form not in view
|
# Admin user assets define, let user select, save it in form not in view
|
||||||
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
||||||
label=_('Asset'),
|
label=_('Asset'),
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.SelectMultiple(
|
widget=forms.SelectMultiple(
|
||||||
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
||||||
)
|
)
|
||||||
# Form field name can not start with `_`, so redefine it,
|
# Form field name can not start with `_`, so redefine it,
|
||||||
password = forms.CharField(widget=forms.PasswordInput, max_length=100, min_length=8, strip=True,
|
password = forms.CharField(widget=forms.PasswordInput, max_length=100, min_length=8, strip=True,
|
||||||
help_text=_('If also set private key, use that first'), required=False)
|
help_text=_('If also set private key, use that first'), required=False)
|
||||||
# Need use upload private key file except paste private key content
|
# Need use upload private key file except paste private key content
|
||||||
private_key_file = forms.FileField(required=False)
|
private_key_file = forms.FileField(required=False)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
# When update a admin user instance, initial it
|
# When update a admin user instance, initial it
|
||||||
if kwargs.get('instance'):
|
if kwargs.get('instance'):
|
||||||
initial = kwargs.get('initial', {})
|
initial = kwargs.get('initial', {})
|
||||||
initial['assets'] = kwargs['instance'].assets.all()
|
initial['assets'] = kwargs['instance'].assets.all()
|
||||||
super(AdminUserForm, self).__init__(*args, **kwargs)
|
super(AdminUserForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def _save_m2m(self):
|
def _save_m2m(self):
|
||||||
# Save assets relation with admin user
|
# Save assets relation with admin user
|
||||||
super(AdminUserForm, self)._save_m2m()
|
super(AdminUserForm, self)._save_m2m()
|
||||||
assets = self.cleaned_data['assets']
|
assets = self.cleaned_data['assets']
|
||||||
self.instance.assets.clear()
|
self.instance.assets.clear()
|
||||||
self.instance.assets.add(*tuple(assets))
|
self.instance.assets.add(*tuple(assets))
|
||||||
|
|
||||||
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(AdminUserForm, self).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 = ssh_pubkey_gen(private_key)
|
public_key = ssh_pubkey_gen(private_key)
|
||||||
|
|
||||||
if password:
|
if password:
|
||||||
admin_user.password = password
|
admin_user.password = password
|
||||||
if private_key:
|
if private_key:
|
||||||
admin_user.private_key = private_key
|
admin_user.private_key = private_key
|
||||||
admin_user.public_key = public_key
|
admin_user.public_key = public_key
|
||||||
admin_user.save()
|
admin_user.save()
|
||||||
return admin_user
|
return admin_user
|
||||||
|
|
||||||
def clean_private_key_file(self):
|
def clean_private_key_file(self):
|
||||||
private_key_file = self.cleaned_data['private_key_file']
|
private_key_file = self.cleaned_data['private_key_file']
|
||||||
if private_key_file:
|
if private_key_file:
|
||||||
private_key = private_key_file.read()
|
private_key = private_key_file.read()
|
||||||
if not validate_ssh_private_key(private_key):
|
if not validate_ssh_private_key(private_key):
|
||||||
raise forms.ValidationError(_('Invalid private key'))
|
raise forms.ValidationError(_('Invalid private key'))
|
||||||
return private_key
|
return private_key
|
||||||
return private_key_file
|
return private_key_file
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
password = self.cleaned_data['password']
|
password = self.cleaned_data['password']
|
||||||
private_key_file = self.cleaned_data.get('private_key_file', '')
|
private_key_file = self.cleaned_data.get('private_key_file', '')
|
||||||
|
|
||||||
if not (password or private_key_file):
|
if not (password or private_key_file):
|
||||||
raise forms.ValidationError(_('Password and private key file must be input one'))
|
raise forms.ValidationError(_('Password and private key file must be input one'))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AdminUser
|
model = AdminUser
|
||||||
fields = ['name', 'username', 'password', 'private_key_file', 'comment']
|
fields = ['name', 'username', 'password', 'private_key_file', 'comment']
|
||||||
widgets = {
|
widgets = {
|
||||||
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
|
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
|
||||||
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
|
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
|
||||||
}
|
}
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'name': '* required',
|
'name': '* required',
|
||||||
'username': '* required',
|
'username': '* required',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class SystemUserForm(forms.ModelForm):
|
class SystemUserForm(forms.ModelForm):
|
||||||
# Admin user assets define, let user select, save it in form not in view
|
# Admin user assets define, let user select, save it in form not in view
|
||||||
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
||||||
label=_('Asset'),
|
label=_('Asset'),
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.SelectMultiple(
|
widget=forms.SelectMultiple(
|
||||||
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
||||||
)
|
)
|
||||||
asset_groups = forms.ModelMultipleChoiceField(queryset=AssetGroup.objects.all(),
|
asset_groups = forms.ModelMultipleChoiceField(queryset=AssetGroup.objects.all(),
|
||||||
label=_('Asset group'),
|
label=_('Asset group'),
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.SelectMultiple(
|
widget=forms.SelectMultiple(
|
||||||
attrs={'class': 'select2',
|
attrs={'class': 'select2',
|
||||||
'data-placeholder': _('Select asset groups')})
|
'data-placeholder': _('Select asset groups')})
|
||||||
)
|
)
|
||||||
auto_generate_key = forms.BooleanField(initial=True)
|
auto_generate_key = forms.BooleanField(initial=True)
|
||||||
# Form field name can not start with `_`, so redefine it,
|
# Form field name can not start with `_`, so redefine it,
|
||||||
password = forms.CharField(widget=forms.PasswordInput, max_length=100, min_length=8, strip=True,
|
password = forms.CharField(widget=forms.PasswordInput, max_length=100, min_length=8, strip=True,
|
||||||
help_text=_('If also set private key, use that first'), required=False)
|
help_text=_('If also set private key, use that first'), required=False)
|
||||||
# Need use upload private key file except paste private key content
|
# Need use upload private key file except paste private key content
|
||||||
private_key_file = forms.FileField(required=False)
|
private_key_file = forms.FileField(required=False)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
# When update a admin user instance, initial it
|
# When update a admin user instance, initial it
|
||||||
if kwargs.get('instance'):
|
if kwargs.get('instance'):
|
||||||
initial = kwargs.get('initial', {})
|
initial = kwargs.get('initial', {})
|
||||||
initial['assets'] = kwargs['instance'].assets.all()
|
initial['assets'] = kwargs['instance'].assets.all()
|
||||||
initial['asset_groups'] = kwargs['instance'].asset_groups.all()
|
initial['asset_groups'] = kwargs['instance'].asset_groups.all()
|
||||||
super(SystemUserForm, self).__init__(*args, **kwargs)
|
super(SystemUserForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def _save_m2m(self):
|
def _save_m2m(self):
|
||||||
# Save assets relation with admin user
|
# Save assets relation with admin user
|
||||||
super(SystemUserForm, self)._save_m2m()
|
super(SystemUserForm, self)._save_m2m()
|
||||||
assets = self.cleaned_data['assets']
|
assets = self.cleaned_data['assets']
|
||||||
asset_groups = self.cleaned_data['asset_groups']
|
asset_groups = self.cleaned_data['asset_groups']
|
||||||
self.instance.assets.clear()
|
self.instance.assets.clear()
|
||||||
self.instance.assets.add(*tuple(assets))
|
self.instance.assets.add(*tuple(assets))
|
||||||
self.instance.asset_groups.clear()
|
self.instance.asset_groups.clear()
|
||||||
self.instance.asset_groups.add(*tuple(asset_groups))
|
self.instance.asset_groups.add(*tuple(asset_groups))
|
||||||
|
|
||||||
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`
|
||||||
system_user = super(SystemUserForm, self).save(commit=commit)
|
system_user = super(SystemUserForm, self).save(commit=commit)
|
||||||
password = self.cleaned_data['password']
|
password = self.cleaned_data['password']
|
||||||
private_key_file = self.cleaned_data['private_key_file']
|
private_key_file = self.cleaned_data['private_key_file']
|
||||||
|
|
||||||
if password:
|
if password:
|
||||||
system_user.password = password
|
system_user.password = password
|
||||||
print(password)
|
print(password)
|
||||||
# Todo: Validate private key file, and generate public key
|
# Todo: Validate private key file, and generate public key
|
||||||
# Todo: Auto generate private key and public key
|
# Todo: Auto generate private key and public key
|
||||||
if private_key_file:
|
if private_key_file:
|
||||||
system_user.private_key = private_key_file.read().strip()
|
system_user.private_key = private_key_file.read().strip()
|
||||||
system_user.save()
|
system_user.save()
|
||||||
return self.instance
|
return self.instance
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SystemUser
|
model = SystemUser
|
||||||
fields = [
|
fields = [
|
||||||
'name', 'username', 'protocol', 'auto_generate_key', 'password', 'private_key_file', 'as_default',
|
'name', 'username', 'protocol', 'auto_generate_key', 'password', 'private_key_file', 'as_default',
|
||||||
'auto_push', 'auto_update', 'sudo', 'comment', 'shell', 'home', 'uid',
|
'auto_push', 'auto_update', 'sudo', 'comment', 'shell', 'home', 'uid',
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
|
'name': forms.TextInput(attrs={'placeholder': _('Name')}),
|
||||||
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
|
'username': forms.TextInput(attrs={'placeholder': _('Username')}),
|
||||||
}
|
}
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'name': '* required',
|
'name': '* required',
|
||||||
'username': '* required',
|
'username': '* required',
|
||||||
'auth_push': 'Auto push system user to asset',
|
'auth_push': 'Auto push system user to asset',
|
||||||
'auth_update': 'Auto update system user ssh key',
|
'auth_update': 'Auto update system user ssh key',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class AssetTagForm(forms.ModelForm):
|
class AssetTagForm(forms.ModelForm):
|
||||||
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(),
|
||||||
label=_('Asset'),
|
label=_('Asset'),
|
||||||
required=False,
|
required=False,
|
||||||
widget=forms.SelectMultiple(
|
widget=forms.SelectMultiple(
|
||||||
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
attrs={'class': 'select2', 'data-placeholder': _('Select assets')})
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
if kwargs.get('instance', None):
|
if kwargs.get('instance', None):
|
||||||
initial = kwargs.get('initial', {})
|
initial = kwargs.get('initial', {})
|
||||||
initial['assets'] = kwargs['instance'].asset_set.all()
|
initial['assets'] = kwargs['instance'].asset_set.all()
|
||||||
super(AssetTagForm, self).__init__(*args, **kwargs)
|
super(AssetTagForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def _save_m2m(self):
|
def _save_m2m(self):
|
||||||
super(AssetTagForm, self)._save_m2m()
|
assets = self.cleaned_data['assets']
|
||||||
assets = self.cleaned_data['assets']
|
self.instance.assets.clear()
|
||||||
self.instance.asset_set.clear()
|
self.instance.assets.add(*tuple(assets))
|
||||||
self.instance.asset_set.add(*tuple(assets))
|
super(AssetTagForm, self)._save_m2m()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Tag
|
model = Tag
|
||||||
fields = [
|
fields = [
|
||||||
"name",
|
"name",
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'name' : forms.TextInput(attrs={}),
|
'name' : forms.TextInput(attrs={}),
|
||||||
|
|
||||||
}
|
}
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'name': '* required',
|
'name': '* required',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class FileForm(forms.Form):
|
class FileForm(forms.Form):
|
||||||
file = forms.FileField()
|
file = forms.FileField()
|
|
@ -269,6 +269,19 @@ class AssetGroup(models.Model):
|
||||||
def get_default_idc():
|
def get_default_idc():
|
||||||
return IDC.initial()
|
return IDC.initial()
|
||||||
|
|
||||||
|
class Tag(models.Model):
|
||||||
|
name = models.CharField(max_length=64, unique=True, verbose_name=_('Name'))
|
||||||
|
created_time = models.DateTimeField(auto_now_add=True, verbose_name=_('Create time'))
|
||||||
|
created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by'))
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
__str__ = __unicode__
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'tag'
|
||||||
|
|
||||||
|
|
||||||
class Asset(models.Model):
|
class Asset(models.Model):
|
||||||
STATUS_CHOICES = (
|
STATUS_CHOICES = (
|
||||||
|
@ -320,7 +333,7 @@ class Asset(models.Model):
|
||||||
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
|
||||||
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date added'))
|
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date added'))
|
||||||
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
|
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
|
||||||
tags = models.ManyToManyField('Tag', blank=True, verbose_name=_('Tags'))
|
tags = models.ManyToManyField(Tag, related_name='assets', blank=True, verbose_name=_('Tags'))
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return '%(ip)s:%(port)s' % {'ip': self.ip, 'port': self.port}
|
return '%(ip)s:%(port)s' % {'ip': self.ip, 'port': self.port}
|
||||||
|
@ -339,7 +352,7 @@ class Asset(models.Model):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'asset'
|
db_table = 'asset'
|
||||||
unique_together = ('ip', 'port')
|
# unique_together = ('ip', 'port')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def generate_fake(cls, count=100):
|
def generate_fake(cls, count=100):
|
||||||
|
@ -365,18 +378,7 @@ class Asset(models.Model):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
class Tag(models.Model):
|
|
||||||
name = models.CharField(max_length=64, unique=True, verbose_name=_('Name'))
|
|
||||||
created_time = models.DateTimeField(auto_now_add=True, verbose_name=_('Create time'))
|
|
||||||
created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by'))
|
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
__str__ = __unicode__
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
db_table = 'tag'
|
|
||||||
|
|
||||||
|
|
||||||
def init_all_models():
|
def init_all_models():
|
||||||
|
|
|
@ -1,112 +1,172 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import viewsets, serializers,generics
|
from rest_framework import viewsets, serializers,generics
|
||||||
from .models import AssetGroup, Asset, IDC, AdminUser, SystemUser
|
from .models import AssetGroup, Asset, IDC, AdminUser, SystemUser, Tag
|
||||||
from common.mixins import IDInFilterMixin
|
from common.mixins import IDInFilterMixin
|
||||||
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin
|
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin
|
||||||
|
|
||||||
|
|
||||||
class AssetGroupSerializer(serializers.ModelSerializer):
|
class AssetGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
assets_amount = serializers.SerializerMethodField()
|
assets_amount = serializers.SerializerMethodField()
|
||||||
# assets = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
|
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AssetGroup
|
model = AssetGroup
|
||||||
|
list_serializer_class = BulkListSerializer
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_assets_amount(obj):
|
def get_assets_amount(obj):
|
||||||
return obj.assets.count()
|
return obj.assets.count()
|
||||||
|
|
||||||
class AssetUpdateGroupSerializer(serializers.ModelSerializer):
|
class AssetUpdateGroupSerializer(serializers.ModelSerializer):
|
||||||
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
|
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Asset
|
model = Asset
|
||||||
fields = ['id', 'groups']
|
fields = ['id', 'groups']
|
||||||
|
|
||||||
class AssetUpdateSystemUserSerializer(serializers.ModelSerializer):
|
class AssetUpdateSystemUserSerializer(serializers.ModelSerializer):
|
||||||
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
|
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Asset
|
||||||
|
fields = ['id', 'system_users']
|
||||||
|
|
||||||
|
## update the asset group, and add or delete the asset to the group
|
||||||
|
class AssetGroupUpdateSerializer(serializers.ModelSerializer):
|
||||||
|
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||||
|
class Meta:
|
||||||
|
model = AssetGroup
|
||||||
|
fields = ['id', 'assets']
|
||||||
|
|
||||||
|
## update the asset group, and add or delete the system_user to the group
|
||||||
|
class AssetGroupUpdateSystemUserSerializer(serializers.ModelSerializer):
|
||||||
|
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
|
||||||
|
class Meta:
|
||||||
|
model = AssetGroup
|
||||||
|
fields = ['id', 'system_users']
|
||||||
|
|
||||||
|
## update the IDC, and add or delete the assets to the IDC
|
||||||
|
class IDCUpdateAssetsSerializer(serializers.ModelSerializer):
|
||||||
|
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||||
|
class Meta:
|
||||||
|
model = IDC
|
||||||
|
fields = ['id', 'assets']
|
||||||
|
|
||||||
|
## tags API
|
||||||
|
class TagSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
|
assets_amount = serializers.SerializerMethodField()
|
||||||
|
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Tag
|
||||||
|
list_serializer_class = BulkListSerializer
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_assets_amount(obj):
|
||||||
|
return obj.assets.count()
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Asset
|
|
||||||
fields = ['id', 'system_users']
|
|
||||||
|
|
||||||
class AdminUserSerializer(serializers.ModelSerializer):
|
class AdminUserSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||||
model = AdminUser
|
class Meta:
|
||||||
|
model = AdminUser
|
||||||
|
|
||||||
def get_field_names(self, declared_fields, info):
|
def get_field_names(self, declared_fields, info):
|
||||||
fields = super(AdminUserSerializer, self).get_field_names(declared_fields, info)
|
fields = super(AdminUserSerializer, self).get_field_names(declared_fields, info)
|
||||||
fields.append('assets_amount')
|
fields.append('assets_amount')
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
|
|
||||||
class SystemUserSerializer(serializers.ModelSerializer):
|
class SystemUserSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SystemUser
|
model = SystemUser
|
||||||
exclude = ('_password', '_private_key', '_public_key')
|
exclude = ('_password', '_private_key', '_public_key')
|
||||||
|
|
||||||
def get_field_names(self, declared_fields, info):
|
def get_field_names(self, declared_fields, info):
|
||||||
fields = super(SystemUserSerializer, self).get_field_names(declared_fields, info)
|
fields = super(SystemUserSerializer, self).get_field_names(declared_fields, info)
|
||||||
fields.extend(['assets_amount'])
|
fields.extend(['assets_amount'])
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
|
|
||||||
|
class SystemUserUpdateAssetsSerializer(serializers.ModelSerializer):
|
||||||
|
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||||
|
class Meta:
|
||||||
|
model = SystemUser
|
||||||
|
fields = ['id', 'assets']
|
||||||
|
|
||||||
|
|
||||||
|
class SystemUserUpdateAssetGroupSerializer(serializers.ModelSerializer):
|
||||||
|
asset_groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
|
||||||
|
class Meta:
|
||||||
|
model = SystemUser
|
||||||
|
fields = ['id', 'asset_groups']
|
||||||
|
|
||||||
|
|
||||||
class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
# system_users = SystemUserSerializer(many=True, read_only=True)
|
# system_users = SystemUserSerializer(many=True, read_only=True)
|
||||||
# admin_user = AdminUserSerializer(many=False, read_only=True)
|
# admin_user = AdminUserSerializer(many=False, read_only=True)
|
||||||
hardware = serializers.SerializerMethodField()
|
hardware = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
model = Asset
|
model = Asset
|
||||||
list_serializer_class = BulkListSerializer
|
list_serializer_class = BulkListSerializer
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_hardware(obj):
|
def get_hardware(obj):
|
||||||
if obj.cpu:
|
if obj.cpu:
|
||||||
return '%s %s %s' % (obj.cpu, obj.memory, obj.disk)
|
return '%s %s %s' % (obj.cpu, obj.memory, obj.disk)
|
||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def get_field_names(self, declared_fields, info):
|
def get_field_names(self, declared_fields, info):
|
||||||
fields = super(AssetSerializer, self).get_field_names(declared_fields, info)
|
fields = super(AssetSerializer, self).get_field_names(declared_fields, info)
|
||||||
fields.extend(['get_type_display', 'get_env_display'])
|
fields.extend(['get_type_display', 'get_env_display'])
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
|
|
||||||
class AssetGrantedSerializer(serializers.ModelSerializer):
|
class AssetGrantedSerializer(serializers.ModelSerializer):
|
||||||
system_users = SystemUserSerializer(many=True, read_only=True)
|
system_users = SystemUserSerializer(many=True, read_only=True)
|
||||||
is_inherited = serializers.SerializerMethodField()
|
is_inherited = serializers.SerializerMethodField()
|
||||||
system_users_join = serializers.SerializerMethodField()
|
system_users_join = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta(object):
|
class Meta(object):
|
||||||
model = Asset
|
model = Asset
|
||||||
fields = ("id", "hostname", "ip", "port", "system_users", "is_inherited",
|
fields = ("id", "hostname", "ip", "port", "system_users", "is_inherited",
|
||||||
"is_active", "system_users_join", "comment")
|
"is_active", "system_users_join", "comment")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_is_inherited(obj):
|
def get_is_inherited(obj):
|
||||||
if getattr(obj, 'inherited', ''):
|
if getattr(obj, 'inherited', ''):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_system_users_join(obj):
|
def get_system_users_join(obj):
|
||||||
return ', '.join([system_user.username for system_user in obj.system_users.all()])
|
return ', '.join([system_user.username for system_user in obj.system_users.all()])
|
||||||
|
|
||||||
|
|
||||||
class IDCSerializer(serializers.ModelSerializer):
|
class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
assets_amount = serializers.SerializerMethodField()
|
assets_amount = serializers.SerializerMethodField()
|
||||||
|
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IDC
|
model = IDC
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_assets_amount(obj):
|
def get_assets_amount(obj):
|
||||||
return obj.assets.count()
|
return obj.assets.count()
|
||||||
|
|
||||||
def get_field_names(self, declared_fields, info):
|
def get_field_names(self, declared_fields, info):
|
||||||
fields = super(IDCSerializer, self).get_field_names(declared_fields, info)
|
fields = super(IDCSerializer, self).get_field_names(declared_fields, info)
|
||||||
fields.append('assets_amount')
|
fields.append('assets_amount')
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
|
|
||||||
|
class TagUpdateAssetsSerializer(serializers.ModelSerializer):
|
||||||
|
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Tag
|
||||||
|
fields = ['id', 'assets']
|
|
@ -6,30 +6,33 @@
|
||||||
{% block modal_body %}
|
{% block modal_body %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
<p class="text-success text-center">{% trans "Hint: only change the field you want to update." %}</p>
|
<p class="text-success text-center">{% trans "Hint: only change the field you want to update." %}</p>
|
||||||
|
<div class="ydxbd" id="ydxbd" style="display: block;">
|
||||||
<div class="ydxbd" id="ydxbd" style="display: block;">
|
<div>
|
||||||
<div>
|
<p id="tags_p">
|
||||||
<p id="tags_p">
|
<a href="/assets/asset-by-tag/5">
|
||||||
<a href="/assets/asset-by-tag/5">
|
<span class="label label-default">三年质保(0)</span>
|
||||||
<span class="label label-default">三年质保(0)</span>
|
</a>
|
||||||
</a>
|
</p>
|
||||||
</p>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<form method="post" class="form-horizontal" action="" id="fm_asset_bulk_update">
|
<form method="post" class="form-horizontal" action="" id="fm_asset_bulk_update">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label col-sm-2 col-lg-2 " for="id_role">{% trans "Role" %}</label>
|
<label class="control-label col-sm-2 col-lg-2 " for="id_type">{% trans "System Type" %}</label>
|
||||||
<div class=" col-sm-9 col-lg-9 ">
|
<div class=" col-sm-9 col-lg-9 ">
|
||||||
<select class=" select2 form-control" id="id_role" name="role">
|
<select class=" select2 form-control" id="id_type" name="type">
|
||||||
<option value="">---------</option>
|
<option value="">---------</option>
|
||||||
<option value="Admin">{% trans "Admin" %}</option>
|
<option value="Server">{% trans "Server" %}</option>
|
||||||
<option value="User">{% trans "User" %}</option>
|
<option value="VM">{% trans "VM" %}</option>
|
||||||
|
<option value="Switch">{% trans "Switch" %}</option>
|
||||||
|
<option value="Storage">{% trans "Storage" %}</option>
|
||||||
|
<option value="Router">{% trans "Router" %}</option>
|
||||||
|
<option value="Firewall">{% trans "Firewall" %}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
|
|
||||||
<label for="groups" class="col-sm-2 control-label">{% trans 'Groups' %}</label>
|
<div class="form-group">
|
||||||
|
<label for="groups" class="col-sm-2 control-label">{% trans 'Asset Groups' %}</label>
|
||||||
<div class="col-sm-9" id="select2-container">
|
<div class="col-sm-9" id="select2-container">
|
||||||
<select name="groups" id="select2_groups" data-placeholder="{% trans 'Select Group' %}" class="select2 form-control m-b" multiple>
|
<select name="groups" id="select2_groups" data-placeholder="{% trans 'Select Group' %}" class="select2 form-control m-b" multiple>
|
||||||
{% for group in groups %}
|
{% for group in groups %}
|
||||||
|
@ -38,6 +41,18 @@
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="users" class="col-sm-2 control-label">{% trans 'System Users' %}</label>
|
||||||
|
<div class="col-sm-9" id="select2-container">
|
||||||
|
<select name="system_users" id="select2_users" data-placeholder="{% trans 'Select System Users' %}" class="select2 form-control m-b" multiple>
|
||||||
|
{% for system_user in system_users %}
|
||||||
|
<option value="{{ system_user.id }}">{{ system_user.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-9 col-lg-9 col-sm-offset-2">
|
<div class="col-sm-9 col-lg-9 col-sm-offset-2">
|
||||||
<div class="checkbox checkbox-success">
|
<div class="checkbox checkbox-success">
|
||||||
|
@ -48,28 +63,17 @@
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
<label class="control-label col-sm-2 col-lg-2 " for="id_tags">标签集合</label>
|
||||||
|
<div class=" col-sm-9 col-lg-9 ">
|
||||||
<label class="control-label col-sm-2 col-lg-2 " for="id_tags">标签集合</label>
|
<select multiple="multiple" class="select2 form-control" data-placeholder="Select asset tags" id="tags" name="tags">
|
||||||
|
{% for tag in tags %}
|
||||||
|
<option value="{{ tag.id }}">{{ tag.name }}</option>
|
||||||
<div class=" col-sm-9 col-lg-9 ">
|
{% endfor %}
|
||||||
<select multiple="multiple" class="select2 form-control" data-placeholder="Select asset tags" id="tags" name="tags">
|
</select>
|
||||||
<option value="1">物理机</option>
|
<p class="help-block">
|
||||||
<option value="2">虚拟机</option>
|
最多5个标签,单个标签最长8个汉字,按回车确认
|
||||||
<option value="3">数据库备份</option>
|
</p>
|
||||||
<option value="4">亦庄机房</option>
|
</div>
|
||||||
<option value="5">三年质保</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<p class="help-block">
|
|
||||||
最多5个标签,单个标签最长8个汉字,按回车确认
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
{% extends '_modal.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% block modal_id %}asset_group_bulk_update_modal{% endblock %}
|
||||||
|
{% block modal_class %}modal-lg{% endblock %}
|
||||||
|
{% block modal_title%}{% trans "Update Asset Group" %}{% endblock %}
|
||||||
|
{% block modal_body %}
|
||||||
|
{% load bootstrap %}
|
||||||
|
<p class="text-success text-center">{% trans "Hint: only change the field you want to update." %}</p>
|
||||||
|
<form method="post" class="form-horizontal" action="" id="fm_asset_group_bulk_update">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="assets" class="col-sm-2 control-label">{% trans 'Assets' %}</label>
|
||||||
|
<div class="col-sm-9" id="select2-container">
|
||||||
|
<select name="assets" id="select2_groups" data-placeholder="{% trans 'Select Asset' %}" class="select2 form-control m-b" multiple>
|
||||||
|
{% for asset in assets %}
|
||||||
|
<option value="{{ asset.id }}">{{ asset.ip }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="system_users" class="col-sm-2 control-label">{% trans 'System Users' %}</label>
|
||||||
|
<div class="col-sm-9" id="select2-container">
|
||||||
|
<select name="system_users" id="select2_groups" data-placeholder="{% trans 'Select System Users' %}" class="select2 form-control m-b" multiple>
|
||||||
|
{% for system_user in system_users %}
|
||||||
|
<option value="{{ system_user.id }}">{{ system_user.name }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-9 col-lg-9 col-sm-offset-2">
|
||||||
|
<div class="checkbox checkbox-success">
|
||||||
|
<input type="checkbox" name="enable_otp" checked id="id_enable_otp"><label for="id_enable_otp">{% trans 'Enable-OTP' %}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
{% block modal_confirm_id %}btn_asset_group_bulk_update{% endblock %}
|
|
@ -88,29 +88,30 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<table class="table table-hover">
|
<table class="table table-hover" id="system_user_assets_table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<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 'Alive' %}</th>
|
<th>{% trans 'Alive' %}</th>
|
||||||
|
<th>{% trans 'Action' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for asset in page_obj %}
|
{# {% for asset in page_obj %}#}
|
||||||
<tr>
|
{# <tr>#}
|
||||||
<td>{{ asset.hostname }}</td>
|
{# <td>{{ asset.hostname }}</td>#}
|
||||||
<td>{{ asset.ip }}</td>
|
{# <td>{{ asset.ip }}</td>#}
|
||||||
<td>{{ asset.port }}</td>
|
{# <td>{{ asset.port }}</td>#}
|
||||||
<td>Alive</td>
|
{# <td>Alive</td>#}
|
||||||
</tr>
|
{# </tr>#}
|
||||||
{% endfor %}
|
{# {% endfor %}#}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="row">
|
{# <div class="row">#}
|
||||||
{% include '_pagination.html' %}
|
{# {% include '_pagination.html' %}#}
|
||||||
</div>
|
{# </div>#}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -164,15 +165,15 @@
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||||
{% for group in groups %}
|
{% for asset in assets_remain %}
|
||||||
<option value="{{ group.id }}">{{ group.name }}</option>
|
<option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<button type="button" class="btn btn-info btn-sm">{% trans 'Replace' %}</button>
|
<button type="button" class="btn btn-info btn-sm btn-replace-asset-admin_user">{% trans 'Replace' %}</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</form>
|
</form>
|
||||||
|
@ -192,15 +193,15 @@
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<select data-placeholder="{% trans 'Select asset groups' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
<select data-placeholder="{% trans 'Select asset groups' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||||
{% for group in groups %}
|
{% for asset_group in asset_groups %}
|
||||||
<option value="{{ group.id }}">{{ group.name }}</option>
|
<option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<button type="button" class="btn btn-warning btn-sm">{% trans 'Replace' %}</button>
|
<button type="button" class="btn btn-warning btn-sm btn-replace-asset_groups-admin_user">{% trans 'Replace' %}</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</form>
|
</form>
|
||||||
|
@ -218,26 +219,181 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
{# function switch_user_status(obj) {#}
|
Array.prototype.remove = function(val) {
|
||||||
{# var status = $(obj).prop('checked');#}
|
var index = this.indexOf(val);
|
||||||
{##}
|
if (index > -1) {
|
||||||
{# $.ajax({#}
|
this.splice(index, 1);
|
||||||
{# url: "{% url 'users:user-active-api' pk=user.id %}",#}
|
}
|
||||||
{# type: "PUT",#}
|
};
|
||||||
{# data: {#}
|
Array.prototype.unique = function(){
|
||||||
{# 'is_active': status#}
|
var res = [];
|
||||||
{# },#}
|
var json = {};
|
||||||
{# success: function (data, status) {#}
|
for(var i = 0; i < this.length; i++){
|
||||||
{# console.log(data)#}
|
if(!json[this[i]]){
|
||||||
{# },#}
|
res.push(this[i]);
|
||||||
{# error: function () {#}
|
json[this[i]] = 1;
|
||||||
{# console.log('error')#}
|
}
|
||||||
{# }#}
|
}
|
||||||
{# })#}
|
return res;
|
||||||
{# }#}
|
};
|
||||||
$(document).ready(function () {
|
function objectRemove(obj, name, url, data) {
|
||||||
$('.select2').select2();
|
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
|
||||||
});
|
});
|
||||||
</script>
|
}
|
||||||
|
swal({
|
||||||
|
title: 'Are you sure remove ?',
|
||||||
|
text: " [" + name + "] ",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonText: 'Cancel',
|
||||||
|
confirmButtonColor: "#DD6B55",
|
||||||
|
confirmButtonText: 'Confirm',
|
||||||
|
closeOnConfirm: false
|
||||||
|
}, function () {
|
||||||
|
doRemove()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
jumpserver.assets_selected = {};
|
||||||
|
jumpserver.asset_groups_selected = {};
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.select2').select2()
|
||||||
|
.on("select2:select", function (evt) {
|
||||||
|
var data = evt.params.data;
|
||||||
|
jumpserver.assets_selected[data.id] = data.text;
|
||||||
|
jumpserver.asset_groups_selected[data.id] = data.text;
|
||||||
|
})
|
||||||
|
.on('select2:unselect', function(evt) {
|
||||||
|
var data = evt.params.data;
|
||||||
|
delete jumpserver.assets_selected[data.id];
|
||||||
|
delete jumpserver.asset_groups_selected[data.id]
|
||||||
|
});
|
||||||
|
var options = {
|
||||||
|
ele: $('#system_user_assets_table'),
|
||||||
|
buttons: [],
|
||||||
|
order: [],
|
||||||
|
columnDefs: [
|
||||||
|
{targets: 0, createdCell: function (td, cellData, rowData) {
|
||||||
|
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
|
||||||
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
|
}},
|
||||||
|
{targets: 3, createdCell: function (td, cellData) {
|
||||||
|
if (!cellData) {
|
||||||
|
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||||
|
} else {
|
||||||
|
$(td).html('<i class="fa fa-check text-navy"></i>')
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||||
|
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
|
||||||
|
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_remove" data-aid="99991937">{% trans "Remove" %}</a>'.replace('99991937', rowData.id);
|
||||||
|
$(td).html(update_btn + del_btn)
|
||||||
|
}}
|
||||||
|
|
||||||
|
],
|
||||||
|
ajax_url: '{% url "api-assets:asset-list" %}?admin_user_id={{ admin_user.id }}',
|
||||||
|
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
|
||||||
|
{data: "is_active" }, {data: "id"}],
|
||||||
|
op_html: $('#actions').html()
|
||||||
|
};
|
||||||
|
jumpserver.initDataTable(options);
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn-replace-asset-admin_user', function () {
|
||||||
|
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
jumpserver.asset_groups_selected = {};
|
||||||
|
var $data_table = $("#system_user_assets_table").DataTable();
|
||||||
|
var assets = [];
|
||||||
|
$.map(jumpserver.assets_selected, function(value, index) {
|
||||||
|
assets.push(parseInt(index));
|
||||||
|
});
|
||||||
|
assets.unique();
|
||||||
|
var data = [];
|
||||||
|
var admin_user_id = {{ admin_user.id }};
|
||||||
|
var the_url = '{% url "api-assets:asset-list" %}';
|
||||||
|
for (var i=0; i<assets.length; i++) {
|
||||||
|
data.push({"id": assets[i], "admin_user": admin_user_id});
|
||||||
|
}
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
method: 'PATCH'
|
||||||
|
});
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn-replace-asset_groups-admin_user', function () {
|
||||||
|
if (Object.keys(jumpserver.asset_groups_selected).length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
jumpserver.assets_selected = {};
|
||||||
|
var $data_table = $("#system_user_assets_table").DataTable();
|
||||||
|
var asset_groups = [];
|
||||||
|
var assets = [];
|
||||||
|
var data = [];
|
||||||
|
var the_url = '{% url "api-assets:asset-list" %}';
|
||||||
|
$.map(jumpserver.asset_groups_selected, function(value, index) {
|
||||||
|
asset_groups.push(parseInt(index));
|
||||||
|
});
|
||||||
|
$.ajax({
|
||||||
|
url: '{% url "api-assets:asset-group-list" %}?id__in=['+asset_groups.join(',')+']',
|
||||||
|
method: 'GET',
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (result) {
|
||||||
|
for (var i=0; i<result.length; i++) {
|
||||||
|
for (var j=0; j<result[i]['assets'].length; j++) {
|
||||||
|
assets.push(result[i]['assets'][j])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var z=0; z<assets.length; z++) {
|
||||||
|
data.push({"id":assets[z], "admin_user":{{admin_user.id}} });
|
||||||
|
}
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
method: 'PATCH'
|
||||||
|
});
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn_asset_remove', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var the_url = "{% url 'api-assets:admin-user-detail' pk=admin_user.id %}";
|
||||||
|
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
|
||||||
|
var assets = [];
|
||||||
|
var delete_asset_id = $(this).data('aid');
|
||||||
|
$.ajax({
|
||||||
|
url: the_url,
|
||||||
|
method: 'GET',
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (result) {
|
||||||
|
for (var i=0; i<result['assets'].length; i++) {
|
||||||
|
assets.push(result['assets'][i])
|
||||||
|
}
|
||||||
|
assets.remove(delete_asset_id);
|
||||||
|
var data = {"assets": assets};
|
||||||
|
objectRemove($this, name, the_url, data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -23,6 +23,18 @@
|
||||||
<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 %}
|
||||||
|
@ -48,8 +60,72 @@ $(document).ready(function(){
|
||||||
ajax_url: '{% url "api-assets:admin-user-list" %}',
|
ajax_url: '{% url "api-assets:admin-user-list" %}',
|
||||||
columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () {return 'lost'} },
|
columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () {return 'lost'} },
|
||||||
{data: "comment" }, {data: "id" }],
|
{data: "comment" }, {data: "id" }],
|
||||||
|
op_html: $('#actions').html()
|
||||||
};
|
};
|
||||||
jumpserver.initDataTable(options);
|
jumpserver.initDataTable(options);
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn_admin_user_delete', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var $data_table = $("#admin_user_list_table").DataTable();
|
||||||
|
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||||
|
var uid = $this.data('uid');
|
||||||
|
var the_url = '{% url "api-assets:admin-user-detail" pk=99991937 %}'.replace('99991937', uid);
|
||||||
|
objectDelete($this, name, the_url);
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '#btn_bulk_update', function () {
|
||||||
|
var action = $('#slct_bulk_update').val();
|
||||||
|
var $data_table = $('#admin_user_list_table').DataTable();
|
||||||
|
var id_list = [];
|
||||||
|
var plain_id_list = [];
|
||||||
|
$data_table.rows({selected: true}).every(function(){
|
||||||
|
id_list.push({id: this.data().id});
|
||||||
|
plain_id_list.push(this.data().id);
|
||||||
|
});
|
||||||
|
if (plain_id_list.length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var the_url = "{% url 'api-assets:admin-user-list' %}";
|
||||||
|
function doDelete() {
|
||||||
|
swal({
|
||||||
|
title: "{% trans 'Are you sure?' %}",
|
||||||
|
text: "{% trans 'This will delete the selected Admin Users !!!' %}",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: "#DD6B55",
|
||||||
|
confirmButtonText: "{% trans 'Confirm' %}",
|
||||||
|
closeOnConfirm: false
|
||||||
|
}, function() {
|
||||||
|
var success = function() {
|
||||||
|
var msg = "{% trans 'Admin Users Deleted.' %}";
|
||||||
|
swal("{% trans 'Admin Users Delete' %}", msg, "success");
|
||||||
|
$('#admin_user_list_table').DataTable().ajax.reload();
|
||||||
|
};
|
||||||
|
var fail = function() {
|
||||||
|
var msg = "{% trans 'Admin Users Deleting failed.' %}";
|
||||||
|
swal("{% trans 'Admin Users Delete' %}", msg, "error");
|
||||||
|
};
|
||||||
|
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
|
||||||
|
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
jumpserver.checked = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function doUpdate() {
|
||||||
|
|
||||||
|
}
|
||||||
|
switch (action) {
|
||||||
|
case 'delete':
|
||||||
|
doDelete();
|
||||||
|
break;
|
||||||
|
case 'update':
|
||||||
|
doUpdate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -200,7 +200,7 @@
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Asset groups' %}
|
<i class="fa fa-info-circle"></i> {% trans 'Asset groups' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table group_edit">
|
<table class="table group_edit" id="add-asset2group">
|
||||||
<tbody>
|
<tbody>
|
||||||
<form>
|
<form>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -236,7 +236,7 @@
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'System users' %}
|
<i class="fa fa-info-circle"></i> {% trans 'System users' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table group_edit">
|
<table class="table group_edit" id="add-asset2systemuser">
|
||||||
<tbody>
|
<tbody>
|
||||||
<form>
|
<form>
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
|
@ -288,7 +288,7 @@ function updateAssetGroups(groups) {
|
||||||
$.map(jumpserver.groups_selected, function(group_name, index) {
|
$.map(jumpserver.groups_selected, function(group_name, index) {
|
||||||
$('#opt_' + index).remove();
|
$('#opt_' + index).remove();
|
||||||
// change tr html of user groups.
|
// change tr html of user groups.
|
||||||
$('.group_edit tbody').append(
|
$('#add-asset2group tbody').append(
|
||||||
'<tr>' +
|
'<tr>' +
|
||||||
'<td><b class="bdg_group" data-gid="' + index + '">' + group_name + '</b></td>' +
|
'<td><b class="bdg_group" data-gid="' + index + '">' + group_name + '</b></td>' +
|
||||||
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' +
|
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||||
|
@ -316,7 +316,7 @@ function updateAssetSystem(system_users) {
|
||||||
$.map(jumpserver.groups_selected, function(name, index) {
|
$.map(jumpserver.groups_selected, function(name, index) {
|
||||||
$('#opt_' + index).remove();
|
$('#opt_' + index).remove();
|
||||||
|
|
||||||
$('.group_edit tbody').append(
|
$('#add-asset2systemuser tbody').append(
|
||||||
'<tr>' +
|
'<tr>' +
|
||||||
'<td><b class="bdg_group" data-sid="' + index + '">' + name + '</b></td>' +
|
'<td><b class="bdg_group" data-sid="' + index + '">' + name + '</b></td>' +
|
||||||
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_system" type="button"><i class="fa fa-minus"></i></button></td>' +
|
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_system" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||||
|
@ -418,7 +418,6 @@ $(document).ready(function () {
|
||||||
var system_users = $('.bdg_group').map(function () {
|
var system_users = $('.bdg_group').map(function () {
|
||||||
return $(this).data('sid');
|
return $(this).data('sid');
|
||||||
}).get();
|
}).get();
|
||||||
console.log(system_users);
|
|
||||||
updateAssetSystem(system_users)
|
updateAssetSystem(system_users)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -48,10 +48,28 @@
|
||||||
<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 'Alive' %}</th>
|
<th>{% trans 'Alive' %}</th>
|
||||||
|
<th>{% trans 'Action' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
{# {% for asset in assets %}#}
|
||||||
|
{# <tr id="bdg_asset" data-aid="{{ asset.id }}">#}
|
||||||
|
{# <td>{{ asset.hostname }}</td>#}
|
||||||
|
{# <td>{{ asset.ip }}</td>#}
|
||||||
|
{# <td>{{ asset.port }}</td>#}
|
||||||
|
{# {% if asset.is_active %}#}
|
||||||
|
{# <td><i class="fa fa-circle text-navy"></i></td>#}
|
||||||
|
{# {% else %}#}
|
||||||
|
{# <td><i class="fa fa-circle text-danger"></i></td>#}
|
||||||
|
{# {% endif %}#}
|
||||||
|
{# <td>#}
|
||||||
|
{# <a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="{{ asset.id }}">{% trans "Delete" %}</a>#}
|
||||||
|
{# <a class="btn btn-xs btn-info m-l-xs btn_asset_update" data-aid="{{ asset.id }}" href="{% url 'assets:asset-update' pk=asset.id %}">{% trans "Update" %}</a>#}
|
||||||
|
{# </td>#}
|
||||||
|
{# </tr>#}
|
||||||
|
{# {% endfor %}#}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -70,14 +88,14 @@
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<select data-placeholder="{% trans 'Select assets' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
<select data-placeholder="{% trans 'Select assets' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||||
{% for asset in assets_remain %}
|
{% for asset in assets_remain %}
|
||||||
<option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
|
<option value="{{ asset.id }}" id="opt_{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</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">{% trans 'Add' %}</button>
|
<button type="button" class="btn btn-primary btn-sm btn-asset-add-groups">{% trans 'Add' %}</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</form>
|
</form>
|
||||||
|
@ -91,29 +109,29 @@
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Associate system user' %}
|
<i class="fa fa-info-circle"></i> {% trans 'Associate system user' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table">
|
<table class="table system-user-table">
|
||||||
<tbody>
|
<tbody>
|
||||||
<form>
|
<form>
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<select data-placeholder="{% trans 'Select system user' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
<select data-placeholder="{% trans 'Select system user' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||||
{% for system_user in system_users_remain %}
|
{% for system_user in system_users_remain %}
|
||||||
<option value="{{ system_user.id }}">{{ system_user.name }}</option>
|
<option value="{{ system_user.id }}" id="opt_{{ system_user.id }}">{{ system_user.name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<button type="button" class="btn btn-info btn-sm">{% trans 'Associate' %}</button>
|
<button type="button" class="btn btn-info btn-sm btn-asset-add-groups-system-users">{% trans 'Associate' %}</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</form>
|
</form>
|
||||||
{% for system_user in system_users %}
|
{% for system_user in system_users %}
|
||||||
<tr>
|
<tr>
|
||||||
<td ><b>{{ group.name }}</b></td>
|
<td ><b class="bdg_system_user" data-sid={{ system_user.id }}>{{ system_user.name }}</b></td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-danger btn-xs" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
|
<button class="btn btn-danger btn-xs pull-right btn_leave_asset_group" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -132,53 +150,249 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
jumpserver.assets_selected = {};
|
||||||
$('.select2').select2();
|
jumpserver.system_users_selected = {};
|
||||||
var options = {
|
function updateAssetsGroup(assets) {
|
||||||
ele: $('#asset_list_table'),
|
var the_url = "{% url 'api-assets:asset-groups-update' pk=asset_group.id %}";
|
||||||
buttons: [],
|
var body = {
|
||||||
order: [],
|
assets: Object.assign([], assets)
|
||||||
select: [],
|
};
|
||||||
columnDefs: [
|
var success = function(data) {
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
$('select2-selection__rendered').empty();
|
||||||
var detail_btn = '<a href="{% url "perms:asset-permission-detail" pk=99991937 %}">' + cellData + '</a>';
|
$('#groups_selected').val('');
|
||||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
$('#asset_list_table > tbody').empty();
|
||||||
}},
|
$.map(jumpserver.assets_selected, function(asset_ip, index) {
|
||||||
{targets: 2, createdCell: function (td, cellData, rowData) {
|
var url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace(99991937, index);
|
||||||
var dataLength = cellData.length;
|
asset = $.ajax({
|
||||||
$(td).html(dataLength);
|
url: url,
|
||||||
}},
|
method: "GET",
|
||||||
{targets: 3, createdCell: function (td, cellData, rowData) {
|
dataType: "json",
|
||||||
var dataLength = cellData.length;
|
success: function (data, textStatus) {
|
||||||
$(td).html(dataLength);
|
var add_tr = '<tr id="bdg_asset" data-aid="'+data.id+'">'+
|
||||||
}},
|
'<td>'+data.hostname+'</td>'+
|
||||||
{targets: 4, createdCell: function (td, cellData, rowData) {
|
'<td>'+data.ip+'</td>'+
|
||||||
var dataLength = cellData.length;
|
'<td>'+data.port+'</td>'+
|
||||||
$(td).html(dataLength);
|
'<td>status</td>'+
|
||||||
}},
|
'<td>'+
|
||||||
{targets: 5, createdCell: function (td, cellData) {
|
'<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="'+data.id+'">{% trans "Delete" %}</a>'+
|
||||||
if (!cellData) {
|
'<a class="btn btn-xs btn-info m-l-xs btn_asset_update" data-aid="'+data.id+'" href="'+'{% url "assets:asset-update" pk=99991937 %}'.replace(99991937, data.id)+'">{% trans "Update" %}</a>'+
|
||||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
'</td>'+
|
||||||
} else {
|
'</tr>';
|
||||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
(data.is_active == true) ? tr = add_tr.replace('<td>status</td>', '<td><i class="fa fa-circle text-navy"></i></td>'): tr = add_tr.replace('<td>status</td>', '<td><i class="fa fa-circle text-danger"></i></td>');
|
||||||
}
|
$('#asset_list_table > tbody').append(tr);
|
||||||
}},
|
|
||||||
{targets: 6, createdCell: function (td, cellData, rowData) {
|
}
|
||||||
var btn = '<button class="btn btn-danger btn-xs btn_del_permission disabled" id=99991937 type="button" style="float: right;"><i class="fa fa-minus"></i></button>';
|
});
|
||||||
if (rowData.is_inherited) {
|
});
|
||||||
$(td).html(btn)
|
};
|
||||||
} else {
|
APIUpdateAttr({
|
||||||
btn = btn.replace('99991937', cellData);
|
url: the_url,
|
||||||
$(td).html(btn.replace('disabled', ''));
|
body: JSON.stringify(body),
|
||||||
}
|
success: success
|
||||||
}}
|
});
|
||||||
],
|
}
|
||||||
ajax_url: '{% url "api-perms:asset-permission-list" %}?user={{ user.id }}',
|
|
||||||
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets" }, {data: "asset_groups"},
|
function objectDelete(obj, name, url, data) {
|
||||||
{data: "system_users"}, {data: "is_active"}, {data: "id"}]
|
function doDelete() {
|
||||||
};
|
var body = data;
|
||||||
jumpserver.initDataTable(options);
|
var success = function() {
|
||||||
})
|
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
|
||||||
</script>
|
$(obj).parent().parent().remove();
|
||||||
|
};
|
||||||
|
var fail = function() {
|
||||||
|
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
|
||||||
|
};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
method: 'PATCH',
|
||||||
|
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()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAssetGroupSystemUsers(system_users) {
|
||||||
|
var the_url = "{% url 'api-assets:asset-groups-update-systemusers' pk=asset_group.id %}";
|
||||||
|
var body = {
|
||||||
|
system_users: Object.assign([], system_users)
|
||||||
|
};
|
||||||
|
var success = function(data) {
|
||||||
|
$('.select2-selection__rendered').empty();
|
||||||
|
$('#groups_selected').val('');
|
||||||
|
$.map(jumpserver.system_users_selected, function(system_user, index) {
|
||||||
|
$('#opt_' + index).remove();
|
||||||
|
$('.system-user-table tbody').append(
|
||||||
|
'<tr>' +
|
||||||
|
'<td><b class="bdg_group" data-sid="' + index + '">' + system_user + '</b></td>' +
|
||||||
|
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||||
|
'</tr>'
|
||||||
|
)
|
||||||
|
});
|
||||||
|
jumpserver.system_users_selected = {};
|
||||||
|
};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
success: success
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.prototype.remove = function(val) {
|
||||||
|
var index = this.indexOf(val);
|
||||||
|
if (index > -1) {
|
||||||
|
this.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.unique = function(){
|
||||||
|
var res = [];
|
||||||
|
var json = {};
|
||||||
|
for(var i = 0; i < this.length; i++){
|
||||||
|
if(!json[this[i]]){
|
||||||
|
res.push(this[i]);
|
||||||
|
json[this[i]] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.select2').select2()
|
||||||
|
.on("select2:select", function (evt) {
|
||||||
|
var data = evt.params.data;
|
||||||
|
jumpserver.assets_selected[data.id] = data.text;
|
||||||
|
jumpserver.system_users_selected[data.id] = data.text;
|
||||||
|
})
|
||||||
|
.on('select2:unselect', function(evt) {
|
||||||
|
var data = evt.params.data;
|
||||||
|
delete jumpserver.assets_selected[data.id];
|
||||||
|
delete jumpserver.system_users_selected[data.id]
|
||||||
|
});
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
ele: $('#asset_list_table'),
|
||||||
|
buttons: [],
|
||||||
|
order: [],
|
||||||
|
columnDefs: [
|
||||||
|
{targets: 0, createdCell: function (td, cellData, rowData) {
|
||||||
|
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
|
||||||
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
|
}},
|
||||||
|
{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=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
|
||||||
|
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Remove" %}</a>'.replace('99991937', 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"}],
|
||||||
|
op_html: $('#actions').html()
|
||||||
|
};
|
||||||
|
jumpserver.initDataTable(options);
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn-asset-add-groups', function () {
|
||||||
|
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
jumpserver.system_users_selected = {};
|
||||||
|
var $data_table = $("#asset_list_table").DataTable();
|
||||||
|
var assets = [];
|
||||||
|
$.ajax({
|
||||||
|
url: '{% url "api-assets:asset-list" %}?asset_group_id={{ asset_group.id }}',
|
||||||
|
method: 'GET',
|
||||||
|
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));
|
||||||
|
});
|
||||||
|
assets.unique();
|
||||||
|
var the_url = "{% url 'api-assets:asset-groups-update' pk=asset_group.id %}";
|
||||||
|
var body = {"assets": assets};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
method: 'PATCH'
|
||||||
|
});
|
||||||
|
{# TODO: reflash the table and reset the jumpserver variables #}
|
||||||
|
{# window.location.href='{% url "assets:asset-group-detail" pk=asset_group.id %}';#}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn_asset_delete', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var the_url = "{% url 'api-assets:asset-groups-update' 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")))
|
||||||
|
});
|
||||||
|
var delete_asset_id = $(this).data('aid');
|
||||||
|
assets.remove(delete_asset_id);
|
||||||
|
var data = {"assets": assets};
|
||||||
|
objectDelete($this, name, the_url, data);
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn-asset-add-groups-system-users', function () {
|
||||||
|
if (Object.keys(jumpserver.system_users_selected).length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
jumpserver.assets_selected = {};
|
||||||
|
var system_users = $('.bdg_system_user').map(function() {
|
||||||
|
return $(this).data('sid');
|
||||||
|
}).get();
|
||||||
|
$.map(jumpserver.system_users_selected, function(value, index) {
|
||||||
|
system_users.push(parseInt(index));
|
||||||
|
$('#opt_' + index).remove();
|
||||||
|
});
|
||||||
|
system_users.unique();
|
||||||
|
updateAssetGroupSystemUsers(system_users);
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn_leave_asset_group', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var $tr = $this.closest('tr');
|
||||||
|
var $badge = $tr.find('.bdg_system_user');
|
||||||
|
var sid = $badge.data('sid');
|
||||||
|
var name = $badge.html() || $badge.text();
|
||||||
|
$('system-user-table').append(
|
||||||
|
'<option value="' + sid + '" id="opt_' + sid + '">' + name + '</option>'
|
||||||
|
);
|
||||||
|
$tr.remove();
|
||||||
|
var system_users = $('.bdg_system_user').map(function () {
|
||||||
|
return $(this).data('sid');
|
||||||
|
}).get();
|
||||||
|
updateAssetGroupSystemUsers(system_users)
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -21,6 +21,20 @@
|
||||||
<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' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content_bottom_left %}{% endblock %}
|
{% block content_bottom_left %}{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
|
@ -43,17 +57,125 @@ $(document).ready(function(){
|
||||||
$(td).html(update_btn + del_btn)
|
$(td).html(update_btn + del_btn)
|
||||||
}}],
|
}}],
|
||||||
ajax_url: '{% url "api-assets:asset-group-list" %}',
|
ajax_url: '{% url "api-assets:asset-group-list" %}',
|
||||||
columns: [{data: "id"}, {data: "name" }, {data: "assets_amount" }, {data: "comment" }, {data: "id"}]
|
columns: [{data: "id"}, {data: "name" }, {data: "assets_amount" }, {data: "comment" }, {data: "id"}],
|
||||||
|
op_html: $('#actions').html()
|
||||||
};
|
};
|
||||||
jumpserver.initDataTable(options);
|
jumpserver.initDataTable(options);
|
||||||
})
|
})
|
||||||
.on('click', '.btn_asset_group_delete', function () {
|
|
||||||
var $this = $(this);
|
.on('click', '.btn_asset_group_delete', function () {
|
||||||
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
var $this = $(this);
|
||||||
var uid = $this.data('uid');
|
var $data_table = $('#asset_groups_list_table').DataTable();
|
||||||
var the_url = '{% url "api-assets:asset-group-detail" pk=99991937 %}'.replace('99991937', uid);
|
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||||
objectDelete($this, name, the_url);
|
var uid = $this.data('uid');
|
||||||
});
|
var the_url = '{% url "api-assets:asset-group-detail" pk=99991937 %}'.replace('99991937', uid);
|
||||||
|
objectDelete($this, name, the_url);
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '#btn_bulk_update', function () {
|
||||||
|
var action = $('#slct_bulk_update').val();
|
||||||
|
var $data_table = $('#asset_groups_list_table').DataTable();
|
||||||
|
var id_list = [];
|
||||||
|
var plain_id_list = [];
|
||||||
|
$data_table.rows({selected: true}).every(function(){
|
||||||
|
id_list.push({id: this.data().id});
|
||||||
|
plain_id_list.push(this.data().id);
|
||||||
|
});
|
||||||
|
if (id_list === []) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var the_url = '{% url "api-assets:asset-group-list" %}';
|
||||||
|
console.log(plain_id_list);
|
||||||
|
console.log(the_url);
|
||||||
|
function doDelete() {
|
||||||
|
swal({
|
||||||
|
title: "{% trans 'Are you sure?' %}",
|
||||||
|
text: "{% trans 'This will delete the selected groups !!!' %}",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: "#DD6B55",
|
||||||
|
confirmButtonText: "{% trans 'Confirm' %}",
|
||||||
|
closeOnConfirm: false
|
||||||
|
}, function() {
|
||||||
|
var success = function() {
|
||||||
|
var msg = "{% trans 'Group Deleted.' %}";
|
||||||
|
swal("{% trans 'Group Delete' %}", msg, "success");
|
||||||
|
$('#asset_groups_list_table').DataTable().ajax.reload();
|
||||||
|
};
|
||||||
|
var fail = function() {
|
||||||
|
var msg = "{% trans 'Group Deleting failed.' %}";
|
||||||
|
swal("{% trans 'Group Delete' %}", msg, "error");
|
||||||
|
};
|
||||||
|
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
|
||||||
|
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
jumpserver.checked = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function doUpdate() {
|
||||||
|
$('#asset_group_bulk_update_modal').modal('show');
|
||||||
|
}
|
||||||
|
switch(action) {
|
||||||
|
case 'delete':
|
||||||
|
doDelete();
|
||||||
|
break;
|
||||||
|
case 'update':
|
||||||
|
doUpdate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '#btn_asset_group_bulk_update', function () {
|
||||||
|
var json_data = $("#fm_asset_group_bulk_update").serializeObject();
|
||||||
|
var body = {};
|
||||||
|
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
|
||||||
|
if (json_data.type != '') {
|
||||||
|
body.type = json_data.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_data.assets != undefined) {
|
||||||
|
body.assets = json_data.assets;
|
||||||
|
}
|
||||||
|
if (typeof body.assets === 'string') {
|
||||||
|
body.assets = [parseInt(body.assets)]
|
||||||
|
} else if(typeof body.assets === 'array') {
|
||||||
|
var new_assets = body.assets.map(Number);
|
||||||
|
body.assets = new_assets;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json_data.system_users != undefined) {
|
||||||
|
body.system_users = json_data.system_users;
|
||||||
|
}
|
||||||
|
if (typeof body.system_users === 'string') {
|
||||||
|
body.system_users = [parseInt(body.system_users)];
|
||||||
|
} else if (typeof body.system_users === 'array') {
|
||||||
|
var new_system_users = body.system_users.map(Number);
|
||||||
|
body.system_users = new_system_users;
|
||||||
|
}
|
||||||
|
|
||||||
|
var post_list = [];
|
||||||
|
var $data_table = $('#asset_groups_list_table').DataTable()
|
||||||
|
$data_table.rows({selected: true}).every(function(){
|
||||||
|
var content = Object.assign({id: this.data().id}, body);
|
||||||
|
post_list.push(content);
|
||||||
|
});
|
||||||
|
if (post_list === []) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
var the_url = '{% url "api-assets:asset-group-list" %}';
|
||||||
|
var success = function() {
|
||||||
|
var msg = "{% trans 'The selected asset groups has been updated successfully.' %}";
|
||||||
|
swal("{% trans 'AssetGroup Updated' %}", msg, "success");
|
||||||
|
$('#asset_groups_list_table').DataTable().ajax.reload();
|
||||||
|
jumpserver.checked = false;
|
||||||
|
};
|
||||||
|
{# console.log(JSON.stringify(post_list));#}
|
||||||
|
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});
|
||||||
|
$('#asset_group_bulk_update_modal').modal('hide');
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
<option value="delete">{% trans 'Delete selected' %}</option>
|
<option value="delete">{% trans 'Delete selected' %}</option>
|
||||||
<option value="update">{% trans 'Update selected' %}</option>
|
<option value="update">{% trans 'Update selected' %}</option>
|
||||||
<option value="deactive">{% trans 'Deactive selected' %}</option>
|
<option value="deactive">{% trans 'Deactive selected' %}</option>
|
||||||
|
<option value="active">{% trans 'Active' %}</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="input-group-btn pull-left" style="padding-left: 5px;">
|
<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">
|
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
|
||||||
|
@ -81,12 +82,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% include 'assets/_asset_import_modal.html' %}
|
{% include 'assets/_asset_import_modal.html' %}
|
||||||
|
{% include 'assets/_asset_bulk_update_modal.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.onload = function (){
|
window.onload = function (){
|
||||||
var tag_on = document.getElementsByName("tag_on");
|
var tag_on = document.getElementsByName("tag_on");
|
||||||
var oDiv = document.getElementById("ydxbd");
|
var oDiv = document.getElementById("ydxbd");
|
||||||
if(tag_on.length > 0){
|
if(tag_on.length > 0){
|
||||||
|
@ -94,100 +96,233 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function tagShow() {
|
function tagShow() {
|
||||||
var oDiv = document.getElementById("ydxbd");
|
var oDiv = document.getElementById("ydxbd");
|
||||||
if (oDiv.style.display == 'none'){
|
if (oDiv.style.display == 'none'){
|
||||||
oDiv.style.display = "block";
|
oDiv.style.display = "block";
|
||||||
}else{
|
}else{
|
||||||
oDiv.style.display = "none";
|
oDiv.style.display = "none";
|
||||||
}
|
}
|
||||||
} //onload;
|
} //onload;
|
||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
var options = {
|
var options = {
|
||||||
ele: $('#asset_list_table'),
|
ele: $('#asset_list_table'),
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}">' + cellData + '</a>';
|
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
}},
|
}},
|
||||||
{targets: 7, createdCell: function (td, cellData) {
|
{targets: 7, 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: 8, createdCell: function (td, cellData) {
|
{targets: 8, createdCell: function (td, cellData) {
|
||||||
if (!cellData) {
|
if (!cellData) {
|
||||||
$(td).html('<i class="fa fa-circle text-danger"></i>')
|
$(td).html('<i class="fa fa-circle text-danger"></i>')
|
||||||
} else {
|
} else {
|
||||||
$(td).html('<i class="fa fa-circle text-navy"></i>')
|
$(td).html('<i class="fa fa-circle text-navy"></i>')
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{targets: 9, createdCell: function (td, cellData, rowData) {
|
{targets: 9, createdCell: function (td, cellData, rowData) {
|
||||||
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
||||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
||||||
$(td).html(update_btn + del_btn)
|
$(td).html(update_btn + del_btn)
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
ajax_url: '{% url "api-assets:asset-list" %}',
|
||||||
|
columns: [{data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "port" },
|
||||||
|
{data: "get_type_display" }, {data: "get_env_display"}, {data: "hardware"},
|
||||||
|
{data: "is_active" }, {data: "is_active"}, {data: "id" }],
|
||||||
|
op_html: $('#actions').html()
|
||||||
|
};
|
||||||
|
var table = jumpserver.initDataTable(options);
|
||||||
|
$('.btn_export').click(function () {
|
||||||
|
var assets = [];
|
||||||
|
var rows = table.rows('.selected').data();
|
||||||
|
$.each(rows, function (index, obj) {
|
||||||
|
assets.push(obj.id)
|
||||||
|
});
|
||||||
|
console.log(assets);
|
||||||
|
$.ajax({
|
||||||
|
url: "{% url "assets:asset-export" %}",
|
||||||
|
method: 'POST',
|
||||||
|
data: JSON.stringify({assets_id: assets}),
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data, textStatus) {
|
||||||
|
window.open(data.redirect)
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
toastr.error('Export failed');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
$('#btn_asset_import').click(function() {
|
||||||
|
var $form = $('#fm_asset_import');
|
||||||
|
$form.find('.help-block').remove();
|
||||||
|
function success (data) {
|
||||||
|
if (data.valid === false) {
|
||||||
|
$('<span />', {class: 'help-block text-danger'}).html(data.msg).insertAfter($('#id_assets'));
|
||||||
|
} else {
|
||||||
|
$('#id_created').html(data.created_info);
|
||||||
|
$('#id_created_detail').html(data.created.join(', '));
|
||||||
|
$('#id_updated').html(data.updated_info);
|
||||||
|
$('#id_updated_detail').html(data.updated.join(', '));
|
||||||
|
$('#id_failed').html(data.failed_info);
|
||||||
|
$('#id_failed_detail').html(data.failed.join(', '));
|
||||||
|
var $data_table = $('#asset_list_table').DataTable();
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$form.ajaxSubmit({success: success});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
}}
|
.on('click', '.btn_asset_delete', function () {
|
||||||
],
|
var $this = $(this);
|
||||||
ajax_url: '{% url "api-assets:asset-list" %}',
|
var $data_table = $("#asset_list_table").DataTable();
|
||||||
columns: [{data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "port" },
|
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||||
{data: "get_type_display" }, {data: "get_env_display"}, {data: "hardware"},
|
var uid = $this.data('uid');
|
||||||
{data: "is_active" }, {data: "is_active"}, {data: "id" }],
|
var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid);
|
||||||
op_html: $('#actions').html()
|
objectDelete($this, name, the_url);
|
||||||
};
|
$data_table.ajax.reload();
|
||||||
var table = jumpserver.initDataTable(options);
|
})
|
||||||
|
|
||||||
$('.btn_export').click(function () {
|
.on('click', '#btn_bulk_update', function () {
|
||||||
var assets = [];
|
var action = $('#slct_bulk_update').val();
|
||||||
var rows = table.rows('.selected').data();
|
var $data_table = $('#asset_list_table').DataTable();
|
||||||
$.each(rows, function (index, obj) {
|
var id_list = [];
|
||||||
assets.push(obj.id)
|
var plain_id_list = [];
|
||||||
});
|
$data_table.rows({selected: true}).every(function(){
|
||||||
$.ajax({
|
id_list.push({id: this.data().id});
|
||||||
url: "{% url "assets:asset-export" %}",
|
plain_id_list.push(this.data().id);
|
||||||
method: 'POST',
|
|
||||||
data: JSON.stringify({assets_id: assets}),
|
|
||||||
dataType: "json",
|
|
||||||
success: function (data, textStatus) {
|
|
||||||
window.open(data.redirect)
|
|
||||||
},
|
|
||||||
error: function () {
|
|
||||||
toastr.error('Export failed');
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#btn_asset_import').click(function() {
|
|
||||||
var $form = $('#fm_asset_import');
|
|
||||||
$form.find('.help-block').remove();
|
|
||||||
function success (data) {
|
|
||||||
if (data.valid === false) {
|
|
||||||
$('<span />', {class: 'help-block text-danger'}).html(data.msg).insertAfter($('#id_assets'));
|
|
||||||
} else {
|
|
||||||
$('#id_created').html(data.created_info);
|
|
||||||
$('#id_created_detail').html(data.created.join(', '));
|
|
||||||
$('#id_updated').html(data.updated_info);
|
|
||||||
$('#id_updated_detail').html(data.updated.join(', '));
|
|
||||||
$('#id_failed').html(data.failed_info);
|
|
||||||
$('#id_failed_detail').html(data.failed.join(', '));
|
|
||||||
var $data_table = $('#asset_list_table').DataTable();
|
|
||||||
$data_table.ajax.reload();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$form.ajaxSubmit({success: success});
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
.on('click', '.btn_asset_delete', function () {
|
|
||||||
var $this = $(this);
|
|
||||||
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
|
||||||
var uid = $this.data('uid');
|
|
||||||
var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid);
|
|
||||||
|
|
||||||
objectDelete($this, name, the_url);
|
|
||||||
});
|
});
|
||||||
|
if (plain_id_list.length == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var the_url = "{% url 'api-assets:asset-list' %}";
|
||||||
|
function doDeactive() {
|
||||||
|
var body = $.each(id_list, function(index, asset_object) {
|
||||||
|
asset_object['is_active'] = false;
|
||||||
|
});
|
||||||
|
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
jumpserver.checked = false;
|
||||||
|
}
|
||||||
|
function doActive() {
|
||||||
|
var body = $.each(id_list, function(index, asset_object) {
|
||||||
|
asset_object['is_active'] = true;
|
||||||
|
});
|
||||||
|
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
jumpserver.checked = false;
|
||||||
|
}
|
||||||
|
function doDelete() {
|
||||||
|
swal({
|
||||||
|
title: "{% trans 'Are you sure?' %}",
|
||||||
|
text: "{% trans 'This will delete the selected assets !!!' %}",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: "#DD6B55",
|
||||||
|
confirmButtonText: "{% trans 'Confirm' %}",
|
||||||
|
closeOnConfirm: false
|
||||||
|
}, function() {
|
||||||
|
var success = function() {
|
||||||
|
var msg = "{% trans 'Asset Deleted.' %}";
|
||||||
|
swal("{% trans 'Asset Delete' %}", msg, "success");
|
||||||
|
$('#asset_list_table').DataTable().ajax.reload();
|
||||||
|
};
|
||||||
|
var fail = function() {
|
||||||
|
var msg = "{% trans 'Asset Deleting failed.' %}";
|
||||||
|
swal("{% trans 'Asset Delete' %}", msg, "error");
|
||||||
|
};
|
||||||
|
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
|
||||||
|
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
jumpserver.checked = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function doUpdate() {
|
||||||
|
$('#asset_bulk_update_modal').modal('show');
|
||||||
|
}
|
||||||
|
switch(action) {
|
||||||
|
case 'deactive':
|
||||||
|
doDeactive();
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
doDelete();
|
||||||
|
break;
|
||||||
|
case 'update':
|
||||||
|
doUpdate();
|
||||||
|
break;
|
||||||
|
case 'active':
|
||||||
|
doActive();
|
||||||
|
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.system_users != undefined) {
|
||||||
|
body.system_users = json_data.system_users;
|
||||||
|
}
|
||||||
|
if (typeof body.system_users === 'string') {
|
||||||
|
body.system_users = [parseInt(body.system_users)]
|
||||||
|
} else if(typeof body.system_users === 'array') {
|
||||||
|
var new_users = body.system_users.map(Number);
|
||||||
|
body.system_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;
|
||||||
|
};
|
||||||
|
console.log(JSON.stringify(post_list));
|
||||||
|
console.log(the_url);
|
||||||
|
{# APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});#}
|
||||||
|
$('#asset_bulk_update_modal').modal('hide');
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -77,80 +77,27 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<table class="table table-hover">
|
<table class="table table-striped table-bordered table-hover " id="tag_assets_table" >
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<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 'Alive' %}</th>
|
<th>{% trans 'Type' %}</th>
|
||||||
|
<th>{% trans 'Valid' %}</th>
|
||||||
|
<th>{% trans 'Action' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for asset in page_obj %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ asset.hostname }}</td>
|
|
||||||
<td>{{ asset.ip }}</td>
|
|
||||||
<td>{{ asset.port }}</td>
|
|
||||||
<td>Alive</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="row">
|
|
||||||
{% include '_pagination.html' %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||||
<div class="panel panel-primary">
|
<div class="panel panel-primary">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Associate system user' %}
|
<i class="fa fa-info-circle"></i> {% trans 'Add asset to this tag' %}
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
<table class="table">
|
|
||||||
<tbody>
|
|
||||||
<tr class="no-borders-tr">
|
|
||||||
<td width="50%">{% trans 'repush system user' %}:</td>
|
|
||||||
<td>
|
|
||||||
<span style="float: right">
|
|
||||||
<button class="btn btn-danger btn-xs" type="button"><i class="fa fa-refresh"></i></button>
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<form>
|
|
||||||
<tr class="no-borders-tr">
|
|
||||||
<td colspan="2">
|
|
||||||
<select data-placeholder="{% trans 'Select system user' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
|
||||||
{% for group in groups %}
|
|
||||||
<option value="{{ group.id }}">{{ group.name }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="no-borders-tr">
|
|
||||||
<td colspan="2">
|
|
||||||
<button type="button" class="btn btn-primary btn-sm">{% trans 'Associate' %}</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</form>
|
|
||||||
{% for group in user.groups.all %}
|
|
||||||
<tr>
|
|
||||||
<td ><b>{{ group.name }}</b></td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger btn-xs" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="panel panel-info">
|
|
||||||
<div class="panel-heading">
|
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Add asset to this group' %}
|
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
|
@ -158,27 +105,19 @@
|
||||||
<form>
|
<form>
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<select data-placeholder="{% trans 'Select asset user' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||||
{% for group in groups %}
|
{% for asset in assets_remain %}
|
||||||
<option value="{{ group.id }}">{{ group.name }}</option>
|
<option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<button type="button" class="btn btn-info btn-sm">{% trans 'Add' %}</button>
|
<button type="button" class="btn btn-info btn-sm btn-tag-asset-add">{% trans 'Add' %}</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</form>
|
</form>
|
||||||
{% for group in user.groups.all %}
|
|
||||||
<tr>
|
|
||||||
<td ><b>{{ group.name }}</b></td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-danger btn-xs" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -194,26 +133,147 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
{# function switch_user_status(obj) {#}
|
jumpserver.assets_selected = {};
|
||||||
{# var status = $(obj).prop('checked');#}
|
|
||||||
{##}
|
function updateTagAssets(assets) {
|
||||||
{# $.ajax({#}
|
var the_url = "{% url 'api-assets:tag-update-assets' pk=tag.id %}";
|
||||||
{# url: "{% url 'users:user-active-api' pk=user.id %}",#}
|
var body = {
|
||||||
{# type: "PUT",#}
|
assets: Object.assign([], assets)
|
||||||
{# data: {#}
|
};
|
||||||
{# 'is_active': status#}
|
var $data_table = $("#tag_assets_table").DataTable();
|
||||||
{# },#}
|
var success = function(data) {
|
||||||
{# success: function (data, status) {#}
|
$('.select2-selection__rendered').empty();
|
||||||
{# console.log(data)#}
|
$.map(jumpserver.assets_selected, function(asset_ip, index) {
|
||||||
{# },#}
|
$('#opt_' + index).remove();
|
||||||
{# error: function () {#}
|
$data_table.ajax.reload();
|
||||||
{# console.log('error')#}
|
});
|
||||||
{# }#}
|
jumpserver.groups_selected = {};
|
||||||
{# })#}
|
};
|
||||||
{# }#}
|
APIUpdateAttr({
|
||||||
$(document).ready(function () {
|
url: the_url,
|
||||||
$('.select2').select2();
|
body: JSON.stringify(body),
|
||||||
})
|
method: 'PUT',
|
||||||
</script>
|
success: success
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function deleteTagAssets(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");
|
||||||
|
};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
method: 'PATCH',
|
||||||
|
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) {
|
||||||
|
var index = this.indexOf(val);
|
||||||
|
if (index > -1) {
|
||||||
|
this.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.select2').select2()
|
||||||
|
.on("select2:select", function (evt) {
|
||||||
|
var data = evt.params.data;
|
||||||
|
jumpserver.assets_selected[data.id] = data.text;
|
||||||
|
})
|
||||||
|
.on('select2:unselect', function(evt) {
|
||||||
|
var data = evt.params.data;
|
||||||
|
delete jumpserver.assets_selected[data.id];
|
||||||
|
});
|
||||||
|
var options = {
|
||||||
|
ele: $('#tag_assets_table'),
|
||||||
|
buttons: [],
|
||||||
|
order: [],
|
||||||
|
columnDefs: [
|
||||||
|
{targets: 0, createdCell: function (td, cellData, rowData) {
|
||||||
|
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
|
||||||
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
|
}},
|
||||||
|
{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=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
|
||||||
|
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Delete" %}</a>'.replace('99991937', rowData.id);
|
||||||
|
$(td).html(update_btn + del_btn)
|
||||||
|
}}
|
||||||
|
|
||||||
|
],
|
||||||
|
ajax_url: '{% url "api-assets:asset-list" %}?tag_id={{ tag.id }}',
|
||||||
|
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
|
||||||
|
{data: "type" }, {data: "is_active" }, {data: "id"}],
|
||||||
|
op_html: $('#actions').html()
|
||||||
|
};
|
||||||
|
jumpserver.initDataTable(options);
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn-tag-asset-add', function () {
|
||||||
|
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var assets=[];
|
||||||
|
var $data_table = $("#tag_assets_table").DataTable();
|
||||||
|
$.ajax({
|
||||||
|
url: '{% url "api-assets:asset-list" %}',
|
||||||
|
method: 'GET',
|
||||||
|
data: {"tag_id": {{ tag.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));
|
||||||
|
});
|
||||||
|
updateTagAssets(assets);
|
||||||
|
$data_table.ajax().reload();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn_asset_delete', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var the_url = "{% url 'api-assets:tag-update-assets' pk=tag.id %}";
|
||||||
|
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
|
||||||
|
var assets = [];
|
||||||
|
$('#tag_assets_table > tbody > tr').map(function () {
|
||||||
|
assets.push(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
|
||||||
|
});
|
||||||
|
var delete_asset_id = $(this).data('aid');
|
||||||
|
assets.remove(delete_asset_id);
|
||||||
|
var data = {"assets": assets};
|
||||||
|
deleteTagAssets($this, name, the_url, data);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,56 +1,126 @@
|
||||||
{% extends '_base_list.html' %}
|
{% extends '_base_list.html' %}
|
||||||
{% load i18n %}
|
{% load i18n static %}
|
||||||
{% load common_tags %}
|
{#{% load common_tags %}#}
|
||||||
{% block content_left_head %}
|
{% block custom_head_css_js %}
|
||||||
<a href="{% url 'assets:asset-tag-create' %}" class="btn btn-sm btn-primary "> {% trans "Create tag" %}</a>
|
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||||
|
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{#{% block content_left_head %}#}
|
||||||
{% block table_head %}
|
{# <a href="{% url 'assets:asset-tag-create' %}" class="btn btn-sm btn-primary "> {% trans "Create tag" %}</a>#}
|
||||||
<th class="text-center">
|
{#{% endblock %}#}
|
||||||
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
|
{#{% block table_head %}#}
|
||||||
</th>
|
{# <th class="text-center">#}
|
||||||
<th class="text-center"><a href="{% url 'assets:asset-tag-list' %}?sort=name">{% trans 'Tag Name' %}</a></th>
|
{# <input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">#}
|
||||||
<th class="text-center">{% trans 'Asset num' %}</th>
|
{# </th>#}
|
||||||
<th class="text-center"></th>
|
{# <th class="text-center"><a href="{% url 'assets:asset-tag-list' %}?sort=name">{% trans 'Tag Name' %}</a></th>#}
|
||||||
{% endblock %}
|
{# <th class="text-center">{% trans 'Asset num' %}</th>#}
|
||||||
|
{# <th class="text-center"></th>#}
|
||||||
{% block table_body %}
|
{#{% endblock %}#}
|
||||||
|
{#{% block table_body %}#}
|
||||||
{% for asset_tag in asset_tags_list %}
|
{# {% for asset_tag in asset_tags_list %}#}
|
||||||
<tr class="gradeX">
|
{# <tr class="gradeX">#}
|
||||||
<td class="text-center">
|
{# <td class="text-center">#}
|
||||||
<input type="checkbox" name="checked" value="{{ asset_tag.id }}">
|
{# <input type="checkbox" name="checked" value="{{ asset_tag.id }}">#}
|
||||||
</td>
|
{# </td>#}
|
||||||
<td class="text-center">
|
{# <td class="text-center">#}
|
||||||
<a href="{% url 'assets:asset-tag-detail' pk=asset_tag.id %}">
|
{# <a href="{% url 'assets:asset-tag-detail' pk=asset_tag.id %}">#}
|
||||||
{{ asset_tag.name }}
|
{# {{ asset_tag.name }}#}
|
||||||
</a>
|
{# </a>#}
|
||||||
</td>
|
{# </td>#}
|
||||||
<td class="text-center">{{ asset_tag.asset_set.count }}</td>
|
{# <td class="text-center">{{ asset_tag.asset_set.count }}</td>#}
|
||||||
<td class="text-center">
|
{# <td class="text-center">#}
|
||||||
<a href="{% url 'assets:asset-tag-update' pk=asset_tag.id %}" class="btn btn-xs btn-info">{% trans 'Update' %}</a>
|
{# <a href="{% url 'assets:asset-tag-update' pk=asset_tag.id %}" class="btn btn-xs btn-info">{% trans 'Update' %}</a>#}
|
||||||
<a onclick="objectDelete(this,'{{ asset_tag.name }}','{% url 'assets:asset-tag-delete' asset_tag.id %}')" class="btn btn-xs btn-danger del">{% trans 'Delete' %}</a>
|
{# <a onclick="objectDelete(this,'{{ asset_tag.name }}','{% url 'assets:asset-tag-delete' asset_tag.id %}')" class="btn btn-xs btn-danger del">{% trans 'Delete' %}</a>#}
|
||||||
</td>
|
{# </td>#}
|
||||||
</tr>
|
{# </tr>#}
|
||||||
{% endfor %}
|
{# {% endfor %}#}
|
||||||
{% endblock %}
|
{#{% endblock %}#}
|
||||||
|
{#{% block content_bottom_left %}#}
|
||||||
{% block content_bottom_left %}
|
{# <form id="" method="get" action="" class=" mail-search">#}
|
||||||
<form id="" method="get" action="" class=" mail-search">
|
{# <div class="input-group">#}
|
||||||
<div class="input-group">
|
{# <select class="form-control m-b" style="width: auto">#}
|
||||||
<select class="form-control m-b" style="width: auto">
|
{# <option>{% trans 'Delete selected' %}</option>#}
|
||||||
<option>{% trans 'Delete selected' %}</option>
|
{# <option>{% trans 'Update selected' %}</option>#}
|
||||||
<option>{% trans 'Update selected' %}</option>
|
{# <option>{% trans 'Deactive selected' %}</option>#}
|
||||||
<option>{% trans 'Deactive selected' %}</option>
|
{# <option>{% trans 'Export selected' %}</option>#}
|
||||||
<option>{% trans 'Export selected' %}</option>
|
{# </select>#}
|
||||||
</select>
|
{# <div class="input-group-btn pull-left" style="padding-left: 5px;">#}
|
||||||
|
{# <button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary">#}
|
||||||
<div class="input-group-btn pull-left" style="padding-left: 5px;">
|
{# {% trans 'Submit' %}#}
|
||||||
<button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary">
|
{# </button>#}
|
||||||
{% trans 'Submit' %}
|
{# </div>#}
|
||||||
</button>
|
{# </div>#}
|
||||||
</div>
|
{# </form>#}
|
||||||
|
{#{% endblock %}#}
|
||||||
|
{% block table_search %}{% endblock %}
|
||||||
|
{% block table_container %}
|
||||||
|
<div class="uc pull-left m-l-5 m-r-5">
|
||||||
|
<a href="{% url "assets:asset-tag-create" %}" class="btn btn-sm btn-primary"> {% trans "Create Tag" %} </a>
|
||||||
|
</div>
|
||||||
|
<table class="table table-striped table-bordered table-hover " id="tag_list_table" >
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
|
||||||
|
<th class="text-center">{% trans 'TagName' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Asset num' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Action' %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div id="actions" class="hide">
|
||||||
|
<div class="input-group">
|
||||||
|
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
|
||||||
|
<option value="delete">{% trans 'Delete selected' %}</option>
|
||||||
|
<option value="update">{% trans 'Update selected' %}</option>
|
||||||
|
</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>
|
||||||
</form>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block custom_foot_js %}
|
||||||
|
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function () {
|
||||||
|
var options = {
|
||||||
|
ele: $("#tag_list_table"),
|
||||||
|
columnDefs:[
|
||||||
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
|
var detail_btn = '<a href="{% url 'assets:asset-tag-detail' pk=99991937 %}">' + cellData + '</a>';
|
||||||
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
|
}},
|
||||||
|
{targets: 3, createdCell: function (td, cellData, rowData) {
|
||||||
|
var update_btn = '<a href="{% url 'assets:asset-tag-detail' pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
||||||
|
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_tag_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
||||||
|
$(td).html(update_btn + del_btn)
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
ajax_url: '{% url "api-assets:asset-tag-list" %}',
|
||||||
|
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets_amount" },{data: "id"}]
|
||||||
|
};
|
||||||
|
jumpserver.initDataTable(options);
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn_tag_delete', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var $data_table = $('#tag_list_table').DataTable();
|
||||||
|
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||||
|
var uid = $this.data('uid');
|
||||||
|
var the_url = '{% url "api-assets:asset-tag-detail" pk=99991937 %}'.replace('99991937', uid);
|
||||||
|
objectDelete($this, name, the_url);
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -7,6 +7,9 @@
|
||||||
{% block custom_head_css_js %}
|
{% block custom_head_css_js %}
|
||||||
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
|
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
|
||||||
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
|
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
</style>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="wrapper wrapper-content animated fadeInRight">
|
<div class="wrapper wrapper-content animated fadeInRight">
|
||||||
|
@ -42,6 +45,7 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<table class="table table-striped table-bordered table-hover " id="idc_assets_table" >
|
<table class="table table-striped table-bordered table-hover " id="idc_assets_table" >
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -59,13 +63,27 @@
|
||||||
<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-warning">
|
||||||
|
{% trans 'Submit' %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||||
<div class="panel panel-primary">
|
<div class="panel panel-primary">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<i class="fa fa-info-circle"></i> {% trans 'Attach to assets ' %}
|
<i class="fa fa-info-circle"></i> {% trans 'Attach assets to IDC ' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<table class="table">
|
<table class="table">
|
||||||
|
@ -75,14 +93,14 @@
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
|
||||||
{% for asset in assets_remain %}
|
{% for asset in assets_remain %}
|
||||||
<option value="{{ asset.id }}">{{ asset.ip}}:{{ asset.port }}</option>
|
<option value="{{ asset.id }}" id="opt_{{ asset.id }}">{{ asset.ip}}:{{ asset.port }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</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">{% trans 'Attach' %}</button>
|
<button type="button" class="btn btn-primary btn-sm btn-asset-attach">{% trans 'Attach Assets' %}</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</form>
|
</form>
|
||||||
|
@ -96,33 +114,255 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% include 'assets/_asset_bulk_update_modal.html' %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script src="{% static 'js/jquery.form.min.js' %}"></script>
|
||||||
$(document).ready(function () {
|
<script>
|
||||||
$('.select2').select2();
|
|
||||||
var options = {
|
jumpserver.assets_selected = {};
|
||||||
ele: $('#idc_assets_table'),
|
|
||||||
buttons: [],
|
Array.prototype.remove = function(val) {
|
||||||
order: [],
|
var index = this.indexOf(val);
|
||||||
columnDefs: [
|
if (index > -1) {
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
this.splice(index, 1);
|
||||||
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}">' + cellData + '</a>';
|
}
|
||||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
};
|
||||||
}},
|
|
||||||
{targets: 5, createdCell: function (td, cellData) {
|
function updateIDCAssets(assets) {
|
||||||
if (!cellData) {
|
var the_url = "{% url 'api-assets:idc-update-assets' pk=idc.id %}";
|
||||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
var body = {
|
||||||
} else {
|
assets: Object.assign([], assets)
|
||||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
};
|
||||||
}
|
var $data_table = $("#idc_assets_table").DataTable();
|
||||||
}}],
|
var success = function(data) {
|
||||||
ajax_url: '{% url "api-assets:asset-list" %}?idc_id={{ idc.id }}',
|
$('.select2-selection__rendered').empty();
|
||||||
columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" },
|
$.map(jumpserver.assets_selected, function(asset_ip, index) {
|
||||||
{data: "type" }, {data: "is_active" }]
|
$('#opt_' + index).remove();
|
||||||
};
|
$data_table.ajax.reload();
|
||||||
jumpserver.initDataTable(options);
|
|
||||||
});
|
});
|
||||||
</script>
|
jumpserver.groups_selected = {};
|
||||||
|
};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
method: 'PUT',
|
||||||
|
success: success
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteIDCAssets(assets) {
|
||||||
|
var the_url = "{% url 'api-assets:idc-update-assets' pk=idc.id %}";
|
||||||
|
var body = {
|
||||||
|
assets: Object.assign([], assets)
|
||||||
|
};
|
||||||
|
var $data_table = $("#idc_assets_table").DataTable();
|
||||||
|
var success = function(data) {
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
method: 'PUT',
|
||||||
|
success: success
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.select2').select2()
|
||||||
|
.on("select2:select", function (evt) {
|
||||||
|
var data = evt.params.data;
|
||||||
|
jumpserver.assets_selected[data.id] = data.text;
|
||||||
|
})
|
||||||
|
.on('select2:unselect', function(evt) {
|
||||||
|
var data = evt.params.data;
|
||||||
|
delete jumpserver.assets_selected[data.id];
|
||||||
|
});
|
||||||
|
var options = {
|
||||||
|
ele: $('#idc_assets_table'),
|
||||||
|
buttons: [],
|
||||||
|
order: [],
|
||||||
|
columnDefs: [
|
||||||
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
|
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
|
||||||
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
|
}},
|
||||||
|
{targets: 5, 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>')
|
||||||
|
}
|
||||||
|
}}],
|
||||||
|
ajax_url: '{% url "api-assets:asset-list" %}?idc_id={{ idc.id }}',
|
||||||
|
columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" },
|
||||||
|
{data: "type" }, {data: "is_active" }],
|
||||||
|
op_html: $('#actions').html()
|
||||||
|
};
|
||||||
|
jumpserver.initDataTable(options);
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn-asset-attach', function () {
|
||||||
|
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var assets=[];
|
||||||
|
var $data_table = $("#idc_assets_table").DataTable();
|
||||||
|
$.ajax({
|
||||||
|
url: '{% url "api-assets:asset-list" %}',
|
||||||
|
method: 'GET',
|
||||||
|
data: {"idc_id": {{ idc.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));
|
||||||
|
});
|
||||||
|
updateIDCAssets(assets);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '#btn_bulk_update', function () {
|
||||||
|
var action = $("#slct_bulk_update").val();
|
||||||
|
var $data_table = $("#idc_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: {"idc_id": {{ idc.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");
|
||||||
|
$('#idc_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:idc-update-assets' pk=idc.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>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -27,7 +27,7 @@
|
||||||
<a class="btn btn-outline btn-default" href="{% url 'assets:idc-update' pk=idc.id %}"><i class="fa fa-edit"></i>Update</a>
|
<a class="btn btn-outline btn-default" href="{% url 'assets:idc-update' pk=idc.id %}"><i class="fa fa-edit"></i>Update</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="pull-right">
|
<li class="pull-right">
|
||||||
<a class="btn btn-outline btn-danger" href="{% url 'assets:idc-delete' pk=idc.id %}">
|
<a class="btn btn-outline btn-danger btn-delete-idc">
|
||||||
<i class="fa fa-edit"></i>Delete
|
<i class="fa fa-edit"></i>Delete
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -53,9 +53,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<table class="table">
|
<table class="table idc-details">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="no-borders-tr">
|
<tr class="no-borders-tr" data-name="{{ idc.name }}">
|
||||||
<td>{% trans 'Name' %}:</td>
|
<td>{% trans 'Name' %}:</td>
|
||||||
<td><b>{{ idc.name }}</b></td>
|
<td><b>{{ idc.name }}</b></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -113,26 +113,47 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
{# function switch_user_status(obj) {#}
|
function idcDelete(name, url) {
|
||||||
{# var status = $(obj).prop('checked');#}
|
function doDelete() {
|
||||||
{##}
|
var body = {};
|
||||||
{# $.ajax({#}
|
var success = function() {
|
||||||
{# url: "{% url 'users:user-active-api' pk=user.id %}",#}
|
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
|
||||||
{# type: "PUT",#}
|
window.location.href="{% url 'assets:idc-list' %}";
|
||||||
{# data: {#}
|
};
|
||||||
{# 'is_active': status#}
|
var fail = function() {
|
||||||
{# },#}
|
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
|
||||||
{# success: function (data, status) {#}
|
};
|
||||||
{# console.log(data)#}
|
APIUpdateAttr({
|
||||||
{# },#}
|
url: url,
|
||||||
{# error: function () {#}
|
body: JSON.stringify(body),
|
||||||
{# console.log('error')#}
|
method: 'DELETE',
|
||||||
{# }#}
|
success: success,
|
||||||
{# })#}
|
error: fail
|
||||||
{# }#}
|
|
||||||
$(document).ready(function () {
|
|
||||||
$('.select2').select2();
|
|
||||||
});
|
});
|
||||||
</script>
|
}
|
||||||
|
swal({
|
||||||
|
title: 'Are you sure delete ?',
|
||||||
|
text: " [" + name + "] ",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonText: 'Cancel',
|
||||||
|
confirmButtonColor: "#DD6B55",
|
||||||
|
confirmButtonText: 'Confirm',
|
||||||
|
closeOnConfirm: false
|
||||||
|
}, function () {
|
||||||
|
doDelete()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.select2').select2();
|
||||||
|
})
|
||||||
|
.on('click', '.btn-delete-idc', function () {
|
||||||
|
var name = $('.idc-details > tbody > tr').attr("data-name");
|
||||||
|
var id = {{ idc.id }};
|
||||||
|
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace(99991937, id);
|
||||||
|
idcDelete(name, the_url);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -1,5 +1,9 @@
|
||||||
{% extends '_base_list.html' %}
|
{% extends '_base_list.html' %}
|
||||||
{% load i18n static %}
|
{% load i18n static %}
|
||||||
|
{% block custom_head_css_js %}
|
||||||
|
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
|
||||||
|
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
|
||||||
|
{% endblock %}
|
||||||
{% block table_search %}{% endblock %}
|
{% block table_search %}{% endblock %}
|
||||||
{% block table_container %}
|
{% block table_container %}
|
||||||
<div class="uc pull-left m-l-5 m-r-5">
|
<div class="uc pull-left m-l-5 m-r-5">
|
||||||
|
@ -22,6 +26,18 @@
|
||||||
<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-warning">
|
||||||
|
{% 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 %}
|
||||||
|
@ -34,20 +50,10 @@ $(document).ready(function(){
|
||||||
var detail_btn = '<a href="{% url "assets:idc-detail" pk=99991937 %}">' + cellData + '</a>';
|
var detail_btn = '<a href="{% url "assets:idc-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
}},
|
}},
|
||||||
{# {targets: 4, createdCell: function (td, cellData) {#}
|
|
||||||
{# var innerHtml = cellData.length > 8 ? cellData.substring(0, 8) + '...': cellData;#}
|
|
||||||
{# $(td).html('<a href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</a>');#}
|
|
||||||
{# }},#}
|
|
||||||
{# {targets: 6, createdCell: function (td, cellData) {#}
|
|
||||||
{# if (!cellData) {#}
|
|
||||||
{# $(td).html('<i class="fa fa-times text-danger"></i>')#}
|
|
||||||
{# } else {#}
|
|
||||||
{# $(td).html('<i class="fa fa-check text-navy"></i>')#}
|
|
||||||
{# }#}
|
|
||||||
{# }},#}
|
|
||||||
{targets: 6, createdCell: function (td, cellData, rowData) {
|
{targets: 6, createdCell: function (td, cellData, rowData) {
|
||||||
var update_btn = '<a href="{% url "assets:idc-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
var update_btn = '<a href="{% url "assets:idc-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
||||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_idc_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
||||||
$(td).html(update_btn + del_btn)
|
$(td).html(update_btn + del_btn)
|
||||||
}}],
|
}}],
|
||||||
ajax_url: '{% url "api-assets:idc-list" %}',
|
ajax_url: '{% url "api-assets:idc-list" %}',
|
||||||
|
@ -56,6 +62,64 @@ $(document).ready(function(){
|
||||||
op_html: $('#actions').html()
|
op_html: $('#actions').html()
|
||||||
};
|
};
|
||||||
jumpserver.initDataTable(options);
|
jumpserver.initDataTable(options);
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn_idc_delete', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var $data_table = $('#idc_list_table').DataTable();
|
||||||
|
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||||
|
var uid = $this.data('uid');
|
||||||
|
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace('99991937', uid);
|
||||||
|
objectDelete($this, name, the_url);
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
{# TODO: reload the tale #}
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '#btn_bulk_update', function () {
|
||||||
|
var action = $('#slct_bulk_update').val();
|
||||||
|
var $data_table = $('#idc_list_table').DataTable();
|
||||||
|
var id_list = [];
|
||||||
|
var plain_id_list = [];
|
||||||
|
$data_table.rows({selected: true}).every(function(){
|
||||||
|
id_list.push({id: this.data().id});
|
||||||
|
plain_id_list.push(this.data().id);
|
||||||
|
});
|
||||||
|
if (id_list === []) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var the_url = "{% url 'api-assets:idc-list' %}";
|
||||||
|
function doDelete() {
|
||||||
|
swal({
|
||||||
|
title: "{% trans 'Are you sure?' %}",
|
||||||
|
text: "{% trans 'This will delete the selected idc !!!' %}",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: "#DD6B55",
|
||||||
|
confirmButtonText: "{% trans 'Confirm' %}",
|
||||||
|
closeOnConfirm: false
|
||||||
|
}, function() {
|
||||||
|
var success = function() {
|
||||||
|
var msg = "{% trans 'IDC Deleted.' %}";
|
||||||
|
swal("{% trans 'IDC Delete' %}", msg, "success");
|
||||||
|
$('#idc_list_table').DataTable().ajax.reload();
|
||||||
|
};
|
||||||
|
var fail = function() {
|
||||||
|
var msg = "{% trans 'IDC Deleting failed.' %}";
|
||||||
|
swal("{% trans 'IDC Delete' %}", msg, "error");
|
||||||
|
};
|
||||||
|
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
|
||||||
|
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
jumpserver.checked = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
switch (action) {
|
||||||
|
case 'delete':
|
||||||
|
doDelete();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -43,35 +43,35 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ibox-content">
|
<div class="ibox-content">
|
||||||
<table class="table table-hover">
|
<table class="table table-hover" id="system_user_list">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<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 'Reachable' %}</th>
|
<th>{% trans 'Reachable' %}</th>
|
||||||
<th></th>
|
<th>{% trans 'Action' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for asset in page_obj %}
|
{# {% for asset in page_obj %}#}
|
||||||
<tr>
|
{# <tr>#}
|
||||||
<td>{{ asset.hostname }}</td>
|
{# <td>{{ asset.hostname }}</td>#}
|
||||||
<td>{{ asset.ip }}</td>
|
{# <td>{{ asset.ip }}</td>#}
|
||||||
<td>{{ asset.port }}</td>
|
{# <td>{{ asset.port }}</td>#}
|
||||||
<td>
|
{# <td>#}
|
||||||
<i class="fa fa-check text-navy"></i>
|
{# <i class="fa fa-check text-navy"></i>#}
|
||||||
</td>
|
{# </td>#}
|
||||||
<td>
|
{# <td>#}
|
||||||
<button class="btn btn-danger pull-right btn-xs {% if asset.is_inherit_from_asset_groups %} disabled {% endif %}" type="button"><i class="fa fa-minus"></i></button>
|
{# <button class="btn btn-danger pull-right btn-xs {% if asset.is_inherit_from_asset_groups %} disabled {% endif %}" type="button"><i class="fa fa-minus"></i></button>#}
|
||||||
</td>
|
{# </td>#}
|
||||||
</tr>
|
{# </tr>#}
|
||||||
{% endfor %}
|
{# {% endfor %}#}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="row">
|
{# <div class="row">#}
|
||||||
{% include '_pagination.html' %}
|
{# {% include '_pagination.html' %}#}
|
||||||
</div>
|
{# </div>#}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -95,7 +95,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">{% trans 'Attach' %}</button>
|
<button type="button" class="btn btn-primary btn-sm btn-add-asset2system-user">{% trans 'Attach Asset' %}</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</form>
|
</form>
|
||||||
|
@ -123,16 +123,16 @@
|
||||||
</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 'Attach' %}</button>
|
<button type="button" class="btn btn-info btn-sm" id="btn_add_user_group">{% trans 'Attach AssetGroup' %}</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{% for asset_group in asset_groups %}
|
{% for asset_group in asset_groups %}
|
||||||
<tr>
|
<tr>
|
||||||
<td ><b data-gid={{ asset_group.id }}>{{ asset_group.name }}</b></td>
|
<td ><b class="bdg_asset_groups" data-gid={{ asset_group.id }}>{{ asset_group.name }}</b></td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-danger pull-right btn-xs" type="button"><i class="fa fa-minus"></i></button>
|
<button class="btn btn-danger pull-right btn-xs btn-leave-system_user" type="button"><i class="fa fa-minus"></i></button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -150,26 +150,224 @@
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
{# function switch_user_status(obj) {#}
|
jumpserver.assets_selected = {};
|
||||||
{# var status = $(obj).prop('checked');#}
|
jumpserver.asset_groups_selected = {};
|
||||||
{##}
|
Array.prototype.remove = function(val) {
|
||||||
{# $.ajax({#}
|
var index = this.indexOf(val);
|
||||||
{# url: "{% url 'users:user-active-api' pk=user.id %}",#}
|
if (index > -1) {
|
||||||
{# type: "PUT",#}
|
this.splice(index, 1);
|
||||||
{# data: {#}
|
}
|
||||||
{# 'is_active': status#}
|
};
|
||||||
{# },#}
|
Array.prototype.unique = function(){
|
||||||
{# success: function (data, status) {#}
|
var res = [];
|
||||||
{# console.log(data)#}
|
var json = {};
|
||||||
{# },#}
|
for(var i = 0; i < this.length; i++){
|
||||||
{# error: function () {#}
|
if(!json[this[i]]){
|
||||||
{# console.log('error')#}
|
res.push(this[i]);
|
||||||
{# }#}
|
json[this[i]] = 1;
|
||||||
{# })#}
|
}
|
||||||
{# }#}
|
}
|
||||||
$(document).ready(function () {
|
return res;
|
||||||
$('.select2').select2();
|
};
|
||||||
|
function objectDelete(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");
|
||||||
|
};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
method: 'PATCH',
|
||||||
|
success: success,
|
||||||
|
error: fail
|
||||||
});
|
});
|
||||||
</script>
|
}
|
||||||
|
swal({
|
||||||
|
title: 'Are you sure delete ?',
|
||||||
|
text: " [" + name + "] ",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
cancelButtonText: 'Cancel',
|
||||||
|
confirmButtonColor: "#DD6B55",
|
||||||
|
confirmButtonText: 'Confirm',
|
||||||
|
closeOnConfirm: false
|
||||||
|
}, function () {
|
||||||
|
doDelete()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function updateSystemUserAssetGroup(asset_groups) {
|
||||||
|
var the_url = "{% url 'api-assets:systemuser-update-assetgroups' pk=system_user.id %}";
|
||||||
|
var body = {
|
||||||
|
asset_groups: Object.assign([], asset_groups)
|
||||||
|
};
|
||||||
|
var success = function(data) {
|
||||||
|
$('.select2-selection__rendered').empty();
|
||||||
|
$('#groups_selected').val('');
|
||||||
|
$.map(jumpserver.asset_groups_selected, function(asset_groups, index) {
|
||||||
|
$('#opt_' + index).remove();
|
||||||
|
$('.system-user-table tbody').append(
|
||||||
|
'<tr>' +
|
||||||
|
'<td><b class="bdg_asset_groups" data-sid="' + index + '">' + asset_groups + '</b></td>' +
|
||||||
|
'<td><button class="btn btn-danger btn-xs pull-right btn-leave-system_user" type="button"><i class="fa fa-minus"></i></button></td>' +
|
||||||
|
'</tr>'
|
||||||
|
)
|
||||||
|
});
|
||||||
|
jumpserver.assets_selected = {};
|
||||||
|
};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
success: success
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.select2').select2()
|
||||||
|
.on("select2:select", function (evt) {
|
||||||
|
var data = evt.params.data;
|
||||||
|
jumpserver.assets_selected[data.id] = data.text;
|
||||||
|
jumpserver.asset_groups_selected[data.id] = data.text;
|
||||||
|
})
|
||||||
|
.on('select2:unselect', function(evt) {
|
||||||
|
var data = evt.params.data;
|
||||||
|
delete jumpserver.assets_selected[data.id];
|
||||||
|
delete jumpserver.asset_groups_selected[data.id];
|
||||||
|
});
|
||||||
|
var options = {
|
||||||
|
ele: $('#system_user_list'),
|
||||||
|
buttons: [],
|
||||||
|
order: [],
|
||||||
|
columnDefs: [
|
||||||
|
{targets: 0, createdCell: function (td, cellData, rowData) {
|
||||||
|
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
|
||||||
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
|
}},
|
||||||
|
{targets: 3, createdCell: function (td, cellData) {
|
||||||
|
if (!cellData) {
|
||||||
|
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||||
|
} else {
|
||||||
|
$(td).html('<i class="fa fa-check text-navy"></i>')
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
{targets: 4, createdCell: function (td, cellData, rowData) {
|
||||||
|
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
|
||||||
|
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Delete" %}</a>'.replace('99991937', rowData.id);
|
||||||
|
$(td).html(update_btn + del_btn)
|
||||||
|
}}
|
||||||
|
],
|
||||||
|
ajax_url: '{% url "api-assets:asset-list" %}?system_user_id={{ system_user.id }}',
|
||||||
|
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" }, {data: function () { return ""; } }, {data: "id"}],
|
||||||
|
op_html: $('#actions').html()
|
||||||
|
};
|
||||||
|
jumpserver.initDataTable(options);
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn-add-asset2system-user', function () {
|
||||||
|
if (Object.keys(jumpserver.assets_selected).length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var $data_table = $("#system_user_list").DataTable();
|
||||||
|
var assets = [];
|
||||||
|
$.ajax({
|
||||||
|
url: '{% url "api-assets:asset-list" %}?system_user_id={{ system_user.id }}',
|
||||||
|
method: 'GET',
|
||||||
|
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));
|
||||||
|
});
|
||||||
|
assets.unique();
|
||||||
|
var the_url = "{% url 'api-assets:systemuser-update-assets' pk=system_user.id %}";
|
||||||
|
var body = {"assets": assets};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
method: 'PATCH'
|
||||||
|
});
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn_asset_delete', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var the_url = "{% url 'api-assets:systemuser-update-assets' pk=system_user.id %}";
|
||||||
|
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
|
||||||
|
var $data_table = $("#system_user_list").DataTable();
|
||||||
|
var assets = [];
|
||||||
|
$('#system_user_list > tbody > tr').map(function () {
|
||||||
|
assets.push(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
|
||||||
|
});
|
||||||
|
var delete_asset_id = $(this).data('aid');
|
||||||
|
assets.remove(delete_asset_id);
|
||||||
|
assets.unique();
|
||||||
|
var data = {"assets": assets};
|
||||||
|
objectDelete($this, name, the_url, data);
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '#btn_add_user_group', function () {
|
||||||
|
jumpserver.assets_selected = {};
|
||||||
|
if (Object.keys(jumpserver.asset_groups_selected).length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
asset_groups = [];
|
||||||
|
$.ajax({
|
||||||
|
url: '{% url "api-assets:systemuser-update-assetgroups" pk=system_user.id %}',
|
||||||
|
method: 'GET',
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (result) {
|
||||||
|
for (var i in result['asset_groups']) {
|
||||||
|
if (!isNaN(result['asset_groups'][i])) {
|
||||||
|
asset_groups.push(parseInt(result['asset_groups'][i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$.map(jumpserver.asset_groups_selected, function(value, index) {
|
||||||
|
asset_groups.push(parseInt(index));
|
||||||
|
});
|
||||||
|
asset_groups.unique();
|
||||||
|
console.log(asset_groups);
|
||||||
|
var the_url = '{% url "api-assets:systemuser-update-assetgroups" pk=system_user.id %}';
|
||||||
|
var body = {"asset_groups": asset_groups};
|
||||||
|
APIUpdateAttr({
|
||||||
|
url: the_url,
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
method: 'PATCH'
|
||||||
|
});
|
||||||
|
{# TODO: reload the table #}
|
||||||
|
{# window.location.href="{% url 'assets:system-user-asset' pk=system_user.id %}"#}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn-leave-system_user', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var $tr = $this.closest('tr');
|
||||||
|
var $badge = $tr.find('.bdg_asset_groups');
|
||||||
|
var sid = $badge.data('gid');
|
||||||
|
var name = $badge.html() || $badge.text();
|
||||||
|
$('system-user-table').append(
|
||||||
|
'<option value="' + sid + '" id="opt_' + sid + '">' + name + '</option>'
|
||||||
|
);
|
||||||
|
$tr.remove();
|
||||||
|
var asset_groups = $('.bdg_asset_groups').map(function () {
|
||||||
|
return $(this).data('gid');
|
||||||
|
}).get();
|
||||||
|
updateSystemUserAssetGroup(asset_groups);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -26,33 +26,110 @@
|
||||||
<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-warning">
|
||||||
|
{% trans 'Submit' %}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
var options = {
|
var options = {
|
||||||
ele: $('#system_user_list_table'),
|
ele: $('#system_user_list_table'),
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{targets: 1, createdCell: function (td, cellData, rowData) {
|
{targets: 1, createdCell: function (td, cellData, rowData) {
|
||||||
var detail_btn = '<a href="{% url "assets:system-user-detail" pk=99991937 %}">' + cellData + '</a>';
|
var detail_btn = '<a href="{% url "assets:system-user-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
}},
|
}},
|
||||||
{targets: 5, createdCell: function (td, cellData) {
|
{targets: 5, createdCell: function (td, cellData) {
|
||||||
var innerHtml = cellData.length > 30 ? cellData.substring(0, 30) + '...': cellData;
|
var innerHtml = cellData.length > 30 ? cellData.substring(0, 30) + '...': cellData;
|
||||||
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
|
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
|
||||||
}},
|
}},
|
||||||
{targets: 6, createdCell: function (td, cellData, rowData) {
|
{targets: 6, createdCell: function (td, cellData, rowData) {
|
||||||
var script_btn = '<a href="{% url "assets:system-user-update" pk=99991937 %}" class="btn btn-xs btn-primary">{% trans "Script" %}</a>'.replace('99991937', cellData);
|
var script_btn = '<a href="{% url "assets:system-user-update" pk=99991937 %}" class="btn btn-xs btn-primary">{% trans "Script" %}</a>'.replace('99991937', cellData);
|
||||||
var update_btn = '<a href="{% url "assets:system-user-update" pk=99991937 %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
var update_btn = '<a href="{% url "assets:system-user-update" pk=99991937 %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
|
||||||
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
|
||||||
$(td).html(script_btn + update_btn + del_btn)
|
$(td).html(script_btn + update_btn + del_btn)
|
||||||
}}],
|
}}],
|
||||||
ajax_url: '{% url "api-assets:system-user-list" %}',
|
ajax_url: '{% url "api-assets:system-user-list" %}',
|
||||||
columns: [{data: "id" }, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () { return "3"}},
|
columns: [{data: "id" }, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () { return "3"}},
|
||||||
{data: "comment" }, {data: "id" }],
|
{data: "comment" }, {data: "id" }],
|
||||||
|
op_html: $('#actions').html()
|
||||||
};
|
};
|
||||||
jumpserver.initDataTable(options);
|
jumpserver.initDataTable(options);
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '.btn_admin_user_delete', function () {
|
||||||
|
var $this = $(this);
|
||||||
|
var $data_table = $('#idc_list_table').DataTable();
|
||||||
|
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
|
||||||
|
var uid = $this.data('uid');
|
||||||
|
var the_url = '{% url "api-assets:system-user-detail" pk=99991937 %}'.replace('99991937', uid);
|
||||||
|
objectDelete($this, name, the_url);
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
})
|
||||||
|
|
||||||
|
.on('click', '#btn_bulk_update', function () {
|
||||||
|
var action = $('#slct_bulk_update').val();
|
||||||
|
var $data_table = $('#system_user_list_table').DataTable();
|
||||||
|
var id_list = [];
|
||||||
|
var plain_id_list = [];
|
||||||
|
$data_table.rows({selected: true}).every(function(){
|
||||||
|
id_list.push({id: this.data().id});
|
||||||
|
plain_id_list.push(this.data().id);
|
||||||
});
|
});
|
||||||
|
if (id_list === []) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var the_url = "{% url 'api-assets:system-user-list' %}";
|
||||||
|
function doDelete() {
|
||||||
|
swal({
|
||||||
|
title: "{% trans 'Are you sure?' %}",
|
||||||
|
text: "{% trans 'This will delete the selected System Users !!!' %}",
|
||||||
|
type: "warning",
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonColor: "#DD6B55",
|
||||||
|
confirmButtonText: "{% trans 'Confirm' %}",
|
||||||
|
closeOnConfirm: false
|
||||||
|
}, function() {
|
||||||
|
var success = function() {
|
||||||
|
var msg = "{% trans 'System Users Deleted.' %}";
|
||||||
|
swal("{% trans 'System Users Delete' %}", msg, "success");
|
||||||
|
$('#system_user_list_table').DataTable().ajax.reload();
|
||||||
|
};
|
||||||
|
var fail = function() {
|
||||||
|
var msg = "{% trans 'System Users Deleting failed.' %}";
|
||||||
|
swal("{% trans 'System Users Delete' %}", msg, "error");
|
||||||
|
};
|
||||||
|
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
|
||||||
|
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
|
||||||
|
$data_table.ajax.reload();
|
||||||
|
jumpserver.checked = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function doUpdate() {
|
||||||
|
{# TODO: bulk update the System Users #}
|
||||||
|
}
|
||||||
|
switch (action) {
|
||||||
|
case 'delete':
|
||||||
|
doDelete();
|
||||||
|
break;
|
||||||
|
case 'update':
|
||||||
|
doUpdate();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -2,16 +2,18 @@
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from .. import api
|
from .. import api
|
||||||
from rest_framework import routers
|
from rest_framework import routers
|
||||||
|
from rest_framework_bulk.routes import BulkRouter
|
||||||
|
|
||||||
app_name = 'assets'
|
app_name = 'assets'
|
||||||
|
|
||||||
|
|
||||||
router = routers.DefaultRouter()
|
router = BulkRouter()
|
||||||
router.register(r'v1/asset-groups', api.AssetGroupViewSet, 'asset-group')
|
router.register(r'v1/asset-groups', api.AssetGroupViewSet, 'asset-group')
|
||||||
router.register(r'v1/assets', api.AssetViewSet, 'asset')
|
router.register(r'v1/assets', api.AssetViewSet, 'asset')
|
||||||
router.register(r'v1/idc', api.IDCViewSet, 'idc')
|
router.register(r'v1/idc', api.IDCViewSet, 'idc')
|
||||||
router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user')
|
router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user')
|
||||||
router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user')
|
router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user')
|
||||||
|
router.register(r'v1/tags', api.TagViewSet, 'asset-tag')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^v1/assets_bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'),
|
url(r'^v1/assets_bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'),
|
||||||
|
@ -20,8 +22,31 @@ urlpatterns = [
|
||||||
|
|
||||||
url(r'^v1/assets/(?P<pk>\d+)/groups/$',
|
url(r'^v1/assets/(?P<pk>\d+)/groups/$',
|
||||||
api.AssetUpdateGroupApi.as_view(), name='asset-update-group'),
|
api.AssetUpdateGroupApi.as_view(), name='asset-update-group'),
|
||||||
|
|
||||||
url(r'^v1/assets/(?P<pk>\d+)/system-users/$',
|
url(r'^v1/assets/(?P<pk>\d+)/system-users/$',
|
||||||
api.SystemUserUpdateApi.as_view(), name='asset-update-systemusers'),
|
api.SystemUserUpdateApi.as_view(), name='asset-update-systemusers'),
|
||||||
|
|
||||||
|
## update the system users, which add and delete the asset to the system user
|
||||||
|
url(r'^v1/system_user/(?P<pk>\d+)/assets/$',
|
||||||
|
api.SystemUserUpdateAssetsApi.as_view(), name='systemuser-update-assets'),
|
||||||
|
|
||||||
|
url(r'^v1/system_user/(?P<pk>\d+)/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>\d+)/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>\d+)/system-users/$',
|
||||||
|
api.AssetGroupUpdateSystemUserApi.as_view(), name='asset-groups-update-systemusers'),
|
||||||
|
## update the IDC, and add or delete the assets to the IDC
|
||||||
|
url(r'^v1/idc/(?P<pk>\d+)/assets/$',
|
||||||
|
api.IDCupdateAssetsApi.as_view(), name='idc-update-assets'),
|
||||||
|
|
||||||
|
url(r'v1/tag/(?P<pk>\d+)/assets/$',
|
||||||
|
api.TagUpdateAssetsApi.as_view(), name='tag-update-assets'),
|
||||||
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns += router.urls
|
urlpatterns += router.urls
|
||||||
|
|
1272
apps/assets/views.py
1272
apps/assets/views.py
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue