资产相关API及Web

pull/530/head
右书僮 2017-01-06 20:34:24 +08:00
parent 4c06257070
commit dbdb8a58fe
21 changed files with 3190 additions and 1530 deletions

View File

@ -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,)

View File

@ -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()

View File

@ -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():

View File

@ -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']

View File

@ -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>

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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)
}) })

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -1,56 +1,126 @@
{% extends '_base_list.html' %} {% extends '_base_list.html' %}
{% load i18n %} {% load i18n static %}
{% load common_tags %} {#{% load common_tags %}#}
{% block content_left_head %} {% block custom_head_css_js %}
<a href="{% url 'assets:asset-tag-create' %}" class="btn btn-sm btn-primary "> {% trans "Create tag" %}</a> <link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
{% endblock %} {% endblock %}
{#{% block content_left_head %}#}
{% block table_head %} {# <a href="{% url 'assets:asset-tag-create' %}" class="btn btn-sm btn-primary "> {% trans "Create tag" %}</a>#}
<th class="text-center"> {#{% endblock %}#}
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')"> {#{% block table_head %}#}
</th> {# <th class="text-center">#}
<th class="text-center"><a href="{% url 'assets:asset-tag-list' %}?sort=name">{% trans 'Tag Name' %}</a></th> {# <input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">#}
<th class="text-center">{% trans 'Asset num' %}</th> {# </th>#}
<th class="text-center"></th> {# <th class="text-center"><a href="{% url 'assets:asset-tag-list' %}?sort=name">{% trans 'Tag Name' %}</a></th>#}
{% endblock %} {# <th class="text-center">{% trans 'Asset num' %}</th>#}
{# <th class="text-center"></th>#}
{% block table_body %} {#{% endblock %}#}
{#{% block table_body %}#}
{% for asset_tag in asset_tags_list %} {# {% for asset_tag in asset_tags_list %}#}
<tr class="gradeX"> {# <tr class="gradeX">#}
<td class="text-center"> {# <td class="text-center">#}
<input type="checkbox" name="checked" value="{{ asset_tag.id }}"> {# <input type="checkbox" name="checked" value="{{ asset_tag.id }}">#}
</td> {# </td>#}
<td class="text-center"> {# <td class="text-center">#}
<a href="{% url 'assets:asset-tag-detail' pk=asset_tag.id %}"> {# <a href="{% url 'assets:asset-tag-detail' pk=asset_tag.id %}">#}
{{ asset_tag.name }} {# {{ asset_tag.name }}#}
</a> {# </a>#}
</td> {# </td>#}
<td class="text-center">{{ asset_tag.asset_set.count }}</td> {# <td class="text-center">{{ asset_tag.asset_set.count }}</td>#}
<td class="text-center"> {# <td class="text-center">#}
<a href="{% url 'assets:asset-tag-update' pk=asset_tag.id %}" class="btn btn-xs btn-info">{% trans 'Update' %}</a> {# <a href="{% url 'assets:asset-tag-update' pk=asset_tag.id %}" class="btn btn-xs btn-info">{% trans 'Update' %}</a>#}
<a onclick="objectDelete(this,'{{ asset_tag.name }}','{% url 'assets:asset-tag-delete' asset_tag.id %}')" class="btn btn-xs btn-danger del">{% trans 'Delete' %}</a> {# <a onclick="objectDelete(this,'{{ asset_tag.name }}','{% url 'assets:asset-tag-delete' asset_tag.id %}')" class="btn btn-xs btn-danger del">{% trans 'Delete' %}</a>#}
</td> {# </td>#}
</tr> {# </tr>#}
{% endfor %} {# {% endfor %}#}
{% endblock %} {#{% endblock %}#}
{#{% block content_bottom_left %}#}
{% block content_bottom_left %} {# <form id="" method="get" action="" class=" mail-search">#}
<form id="" method="get" action="" class=" mail-search"> {# <div class="input-group">#}
<div class="input-group"> {# <select class="form-control m-b" style="width: auto">#}
<select class="form-control m-b" style="width: auto"> {# <option>{% trans 'Delete selected' %}</option>#}
<option>{% trans 'Delete selected' %}</option> {# <option>{% trans 'Update selected' %}</option>#}
<option>{% trans 'Update selected' %}</option> {# <option>{% trans 'Deactive selected' %}</option>#}
<option>{% trans 'Deactive selected' %}</option> {# <option>{% trans 'Export selected' %}</option>#}
<option>{% trans 'Export selected' %}</option> {# </select>#}
</select> {# <div class="input-group-btn pull-left" style="padding-left: 5px;">#}
{# <button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary">#}
<div class="input-group-btn pull-left" style="padding-left: 5px;"> {# {% trans 'Submit' %}#}
<button id='search_btn' type="submit" style="height: 32px;" class="btn btn-sm btn-primary"> {# </button>#}
{% trans 'Submit' %} {# </div>#}
</button> {# </div>#}
</div> {# </form>#}
{#{% endblock %}#}
{% block table_search %}{% endblock %}
{% block table_container %}
<div class="uc pull-left m-l-5 m-r-5">
<a href="{% url "assets:asset-tag-create" %}" class="btn btn-sm btn-primary"> {% trans "Create Tag" %} </a>
</div>
<table class="table table-striped table-bordered table-hover " id="tag_list_table" >
<thead>
<tr>
<th class="text-center"><input type="checkbox" class="ipt_check_all"></th>
<th class="text-center">{% trans 'TagName' %}</th>
<th class="text-center">{% trans 'Asset num' %}</th>
<th class="text-center">{% trans 'Action' %}</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div> </div>
</form> </div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script>
<script type="text/javascript">
$(document).ready(function () {
var options = {
ele: $("#tag_list_table"),
columnDefs:[
{targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url 'assets:asset-tag-detail' pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url 'assets:asset-tag-detail' pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_tag_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-tag-list" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets_amount" },{data: "id"}]
};
jumpserver.initDataTable(options);
})
.on('click', '.btn_tag_delete', function () {
var $this = $(this);
var $data_table = $('#tag_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:asset-tag-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
</script>
{% endblock %} {% endblock %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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

File diff suppressed because it is too large Load Diff