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 %} | {% 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 %} | ||||||
|  | @ -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
	
	 右书僮
						右书僮