Commit dbdb8a58 authored by 右书僮's avatar 右书僮

资产相关API及Web

parent 4c062570
...@@ -3,66 +3,106 @@ ...@@ -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):
queryset = super(AssetViewSet, self).get_queryset()
idc_id = self.request.query_params.get('idc_id', '')
tags_id = self.request.query_params.get('tag_id', '')
system_users_id = self.request.query_params.get('system_user_id', '')
asset_group_id = self.request.query_params.get('asset_group_id', '')
admin_user_id = self.request.query_params.get('admin_user_id', '')
if idc_id:
queryset = queryset.filter(idc__id=idc_id)
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(IDInFilterMixin, BulkModelViewSet):
queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupSerializer
permission_classes = (IsSuperUser,)
def get_queryset(self): class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView):
queryset = super(AssetViewSet, self).get_queryset() queryset = Asset.objects.all()
idc_id = self.request.query_params.get('idc_id', '') serializer_class = serializers.AssetUpdateGroupSerializer
asset_group_id = self.request.query_params.get('asset_group_id', '') permission_classes = (IsSuperUser,)
if idc_id:
queryset = queryset.filter(idc__id=idc_id) ## update the asset group, and add or delete the asset to the group
class AssetGroupUpdateApi(generics.RetrieveUpdateAPIView):
if asset_group_id: queryset = AssetGroup.objects.all()
queryset = queryset.filter(groups__id=asset_group_id) serializer_class = serializers.AssetGroupUpdateSerializer
return queryset permission_classes = (IsSuperUser,)
## update the asset group, and add or delete the system_user to the group
class AssetGroupUpdateSystemUserApi(generics.RetrieveUpdateAPIView):
queryset = AssetGroup.objects.all()
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 AssetGroupViewSet(viewsets.ModelViewSet): class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
""" API endpoint that allows AssetGroup to be viewed or edited. queryset = Asset.objects.all()
some other comment serializer_class = serializers.AssetUpdateSystemUserSerializer
""" permission_classes = (IsSuperUser,)
queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupSerializer
class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView): class SystemUserUpdateAssetsApi(generics.RetrieveUpdateAPIView):
queryset = Asset.objects.all() queryset = SystemUser.objects.all()
serializer_class = serializers.AssetUpdateGroupSerializer serializer_class = serializers.SystemUserUpdateAssetsSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class IDCViewSet(viewsets.ModelViewSet):
"""API endpoint that allows IDC to be viewed or edited."""
queryset = IDC.objects.all()
serializer_class = serializers.IDCSerializer
permission_classes = (IsSuperUser,)
class AdminUserViewSet(viewsets.ModelViewSet):
queryset = AdminUser.objects.all()
serializer_class = serializers.AdminUserSerializer
permission_classes = (IsSuperUser,)
class SystemUserViewSet(viewsets.ModelViewSet):
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserSerializer
permission_classes = (IsSuperUser,)
class SystemUserUpdateApi(generics.RetrieveUpdateAPIView): class SystemUserUpdateAssetGroupApi(generics.RetrieveUpdateAPIView):
queryset = Asset.objects.all() queryset = SystemUser.objects.all()
serializer_class = serializers.AssetUpdateSystemUserSerializer serializer_class = serializers.SystemUserUpdateAssetGroupSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
# class IDCAssetsApi(generics.ListAPIView): # class IDCAssetsApi(generics.ListAPIView):
...@@ -79,39 +119,50 @@ class SystemUserUpdateApi(generics.RetrieveUpdateAPIView): ...@@ -79,39 +119,50 @@ class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView): class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
queryset = Asset.objects.all() queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer serializer_class = serializers.AssetSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class SystemUserAuthApi(APIView): class SystemUserAuthApi(APIView):
permission_classes = (IsSuperUserOrTerminalUser,) permission_classes = (IsSuperUserOrTerminalUser,)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
system_user_id = request.query_params.get('system_user_id', -1) system_user_id = request.query_params.get('system_user_id', -1)
system_user_username = request.query_params.get('system_user_username', '') system_user_username = request.query_params.get('system_user_username', '')
system_user = get_object_or_none(SystemUser, id=system_user_id, username=system_user_username) system_user = get_object_or_none(SystemUser, id=system_user_id, username=system_user_username)
if system_user: if system_user:
if system_user.password: if system_user.password:
password = signer.sign(system_user.password) password = signer.sign(system_user.password)
else: else:
password = signer.sign('') password = signer.sign('')
if system_user.private_key: if system_user.private_key:
private_key = signer.sign(system_user.private_key) private_key = signer.sign(system_user.private_key)
else: else:
private_key = signer.sign(None) private_key = signer.sign(None)
response = { response = {
'id': system_user.id, 'id': system_user.id,
'password': password, 'password': password,
'private_key': private_key, 'private_key': private_key,
} }
return Response(response) return Response(response)
else: else:
return Response({'msg': 'error system user id or username'}, status=401) return Response({'msg': 'error system user id or username'}, status=401)
class TagViewSet(IDInFilterMixin, BulkModelViewSet):
queryset = Tag.objects.all()
serializer_class = serializers.TagSerializer
permission_classes = (IsSuperUser,)
## update the IDC, and add or delete the assets to the IDC
class TagUpdateAssetsApi(generics.RetrieveUpdateAPIView):
queryset = Tag.objects.all()
serializer_class = serializers.TagUpdateAssetsSerializer
permission_classes = (IsSuperUser,)
...@@ -20,297 +20,305 @@ from common.utils import validate_ssh_private_key, ssh_pubkey_gen ...@@ -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()
\ No newline at end of file \ No newline at end of file
...@@ -269,6 +269,19 @@ class AssetGroup(models.Model): ...@@ -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): ...@@ -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): ...@@ -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): ...@@ -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():
......
# -*- 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):
model = Asset
fields = ("id", "hostname", "ip", "port", "system_users", "is_inherited",
"is_active", "system_users_join", "comment")
@staticmethod
def get_is_inherited(obj):
if getattr(obj, 'inherited', ''):
return True
else:
return False
@staticmethod
def get_system_users_join(obj):
return ', '.join([system_user.username for system_user in obj.system_users.all()])
class Meta(object):
model = Asset
fields = ("id", "hostname", "ip", "port", "system_users", "is_inherited",
"is_active", "system_users_join", "comment")
@staticmethod class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer):
def get_is_inherited(obj): assets_amount = serializers.SerializerMethodField()
if getattr(obj, 'inherited', ''): assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
return True
else:
return False
@staticmethod class Meta:
def get_system_users_join(obj): model = IDC
return ', '.join([system_user.username for system_user in obj.system_users.all()])
@staticmethod
def get_assets_amount(obj):
return obj.assets.count()
class IDCSerializer(serializers.ModelSerializer): def get_field_names(self, declared_fields, info):
assets_amount = serializers.SerializerMethodField() fields = super(IDCSerializer, self).get_field_names(declared_fields, info)
fields.append('assets_amount')
return fields
class Meta:
model = IDC
@staticmethod class TagUpdateAssetsSerializer(serializers.ModelSerializer):
def get_assets_amount(obj): assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
return obj.assets.count()
def get_field_names(self, declared_fields, info): class Meta:
fields = super(IDCSerializer, self).get_field_names(declared_fields, info) model = Tag
fields.append('assets_amount') fields = ['id', 'assets']
return fields \ No newline at end of file
...@@ -6,30 +6,33 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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>
......
{% 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 %}
\ No newline at end of file
...@@ -88,29 +88,30 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 %}
\ No newline at end of file
...@@ -23,6 +23,18 @@ ...@@ -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(){ ...@@ -48,8 +60,72 @@ $(document).ready(function(){
ajax_url: '{% url "api-assets:admin-user-list" %}', ajax_url: '{% url "api-assets:admin-user-list" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () {return 'lost'} }, columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () {return 'lost'} },
{data: "comment" }, {data: "id" }], {data: "comment" }, {data: "id" }],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn_admin_user_delete', function () {
var $this = $(this);
var $data_table = $("#admin_user_list_table").DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:admin-user-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#admin_user_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (plain_id_list.length == 0) {
return false;
}
var the_url = "{% url 'api-assets:admin-user-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected Admin Users !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Admin Users Deleted.' %}";
swal("{% trans 'Admin Users Delete' %}", msg, "success");
$('#admin_user_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Admin Users Deleting failed.' %}";
swal("{% trans 'Admin Users Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
}); });
</script> </script>
{% endblock %} {% endblock %}
......
...@@ -200,7 +200,7 @@ ...@@ -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 @@ ...@@ -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) { ...@@ -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) { ...@@ -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 () { ...@@ -418,7 +418,6 @@ $(document).ready(function () {
var system_users = $('.bdg_group').map(function () { var system_users = $('.bdg_group').map(function () {
return $(this).data('sid'); return $(this).data('sid');
}).get(); }).get();
console.log(system_users);
updateAssetSystem(system_users) updateAssetSystem(system_users)
}) })
......
...@@ -48,10 +48,28 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 %}
\ No newline at end of file
...@@ -21,6 +21,20 @@ ...@@ -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(){ ...@@ -43,17 +57,125 @@ $(document).ready(function(){
$(td).html(update_btn + del_btn) $(td).html(update_btn + del_btn)
}}], }}],
ajax_url: '{% url "api-assets:asset-group-list" %}', ajax_url: '{% url "api-assets:asset-group-list" %}',
columns: [{data: "id"}, {data: "name" }, {data: "assets_amount" }, {data: "comment" }, {data: "id"}] columns: [{data: "id"}, {data: "name" }, {data: "assets_amount" }, {data: "comment" }, {data: "id"}],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
}) })
.on('click', '.btn_asset_group_delete', function () {
var $this = $(this); .on('click', '.btn_asset_group_delete', function () {
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html(); var $this = $(this);
var uid = $this.data('uid'); var $data_table = $('#asset_groups_list_table').DataTable();
var the_url = '{% url "api-assets:asset-group-detail" pk=99991937 %}'.replace('99991937', uid); var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
objectDelete($this, name, the_url); var uid = $this.data('uid');
}); var the_url = '{% url "api-assets:asset-group-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#asset_groups_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
var the_url = '{% url "api-assets:asset-group-list" %}';
console.log(plain_id_list);
console.log(the_url);
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected groups !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Group Deleted.' %}";
swal("{% trans 'Group Delete' %}", msg, "success");
$('#asset_groups_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Group Deleting failed.' %}";
swal("{% trans 'Group Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
$('#asset_group_bulk_update_modal').modal('show');
}
switch(action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
})
.on('click', '#btn_asset_group_bulk_update', function () {
var json_data = $("#fm_asset_group_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.assets != undefined) {
body.assets = json_data.assets;
}
if (typeof body.assets === 'string') {
body.assets = [parseInt(body.assets)]
} else if(typeof body.assets === 'array') {
var new_assets = body.assets.map(Number);
body.assets = new_assets;
}
if (json_data.system_users != undefined) {
body.system_users = json_data.system_users;
}
if (typeof body.system_users === 'string') {
body.system_users = [parseInt(body.system_users)];
} else if (typeof body.system_users === 'array') {
var new_system_users = body.system_users.map(Number);
body.system_users = new_system_users;
}
var post_list = [];
var $data_table = $('#asset_groups_list_table').DataTable()
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
});
if (post_list === []) {
return false
}
var the_url = '{% url "api-assets:asset-group-list" %}';
var success = function() {
var msg = "{% trans 'The selected asset groups has been updated successfully.' %}";
swal("{% trans 'AssetGroup Updated' %}", msg, "success");
$('#asset_groups_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
{# console.log(JSON.stringify(post_list));#}
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});
$('#asset_group_bulk_update_modal').modal('hide');
});
</script> </script>
{% endblock %} {% endblock %}
...@@ -72,6 +72,7 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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}), if (plain_id_list.length == 0) {
dataType: "json", return false;
success: function (data, textStatus) { }
window.open(data.redirect) var the_url = "{% url 'api-assets:asset-list' %}";
}, function doDeactive() {
error: function () { var body = $.each(id_list, function(index, asset_object) {
toastr.error('Export failed'); 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;
}
$('#btn_asset_import').click(function() { if (json_data.system_users != undefined) {
var $form = $('#fm_asset_import'); body.system_users = json_data.system_users;
$form.find('.help-block').remove(); }
function success (data) { if (typeof body.system_users === 'string') {
if (data.valid === false) { body.system_users = [parseInt(body.system_users)]
$('<span />', {class: 'help-block text-danger'}).html(data.msg).insertAfter($('#id_assets')); } else if(typeof body.system_users === 'array') {
} else { var new_users = body.system_users.map(Number);
$('#id_created').html(data.created_info); body.system_users = new_users;
$('#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});
})
}) if (json_data.tags != undefined) {
.on('click', '.btn_asset_delete', function () { body.tags = json_data.tags;
var $this = $(this); }
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html(); if (typeof body.tags == 'string') {
var uid = $this.data('uid'); body.tags = [parseInt(body.tags)];
var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid); } else if (typeof body.tags === 'array') {
var new_tags = body.tags.map(Number);
body.tags = new_tags;
}
objectDelete($this, name, the_url); 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 %}
\ No newline at end of file
...@@ -77,80 +77,27 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 %}
\ No newline at end of file
{% 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 %}#}
{# <a href="{% url 'assets:asset-tag-create' %}" class="btn btn-sm btn-primary "> {% trans "Create tag" %}</a>#}
{#{% endblock %}#}
{#{% block table_head %}#}
{# <th class="text-center">#}
{# <input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">#}
{# </th>#}
{# <th class="text-center"><a href="{% url 'assets:asset-tag-list' %}?sort=name">{% trans 'Tag Name' %}</a></th>#}
{# <th class="text-center">{% trans 'Asset num' %}</th>#}
{# <th class="text-center"></th>#}
{#{% endblock %}#}
{#{% block table_body %}#}
{# {% for asset_tag in asset_tags_list %}#}
{# <tr class="gradeX">#}
{# <td class="text-center">#}
{# <input type="checkbox" name="checked" value="{{ asset_tag.id }}">#}
{# </td>#}
{# <td class="text-center">#}
{# <a href="{% url 'assets:asset-tag-detail' pk=asset_tag.id %}">#}
{# {{ asset_tag.name }}#}
{# </a>#}
{# </td>#}
{# <td class="text-center">{{ asset_tag.asset_set.count }}</td>#}
{# <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 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>#}
{# </tr>#}
{# {% endfor %}#}
{#{% endblock %}#}
{#{% block content_bottom_left %}#}
{# <form id="" method="get" action="" class=" mail-search">#}
{# <div class="input-group">#}
{# <select class="form-control m-b" style="width: auto">#}
{# <option>{% trans 'Delete selected' %}</option>#}
{# <option>{% trans 'Update selected' %}</option>#}
{# <option>{% trans 'Deactive selected' %}</option>#}
{# <option>{% trans 'Export selected' %}</option>#}
{# </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">#}
{# {% trans 'Submit' %}#}
{# </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>
</div>
{% block table_head %}
<th class="text-center">
<input type="checkbox" id="check_all" onclick="checkAll('check_all', 'checked')">
</th>
<th class="text-center"><a href="{% url 'assets:asset-tag-list' %}?sort=name">{% trans 'Tag Name' %}</a></th>
<th class="text-center">{% trans 'Asset num' %}</th>
<th class="text-center"></th>
{% endblock %} {% endblock %}
{% block table_body %} {% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script>
{% for asset_tag in asset_tags_list %} <script type="text/javascript">
<tr class="gradeX"> $(document).ready(function () {
<td class="text-center"> var options = {
<input type="checkbox" name="checked" value="{{ asset_tag.id }}"> ele: $("#tag_list_table"),
</td> columnDefs:[
<td class="text-center"> {targets: 1, createdCell: function (td, cellData, rowData) {
<a href="{% url 'assets:asset-tag-detail' pk=asset_tag.id %}"> var detail_btn = '<a href="{% url 'assets:asset-tag-detail' pk=99991937 %}">' + cellData + '</a>';
{{ asset_tag.name }} $(td).html(detail_btn.replace('99991937', rowData.id));
</a> }},
</td> {targets: 3, createdCell: function (td, cellData, rowData) {
<td class="text-center">{{ asset_tag.asset_set.count }}</td> var update_btn = '<a href="{% url 'assets:asset-tag-detail' pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
<td class="text-center"> 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);
<a href="{% url 'assets:asset-tag-update' pk=asset_tag.id %}" class="btn btn-xs btn-info">{% trans 'Update' %}</a> $(td).html(update_btn + del_btn)
<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> ],
</tr> ajax_url: '{% url "api-assets:asset-tag-list" %}',
{% endfor %} columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets_amount" },{data: "id"}]
{% endblock %} };
jumpserver.initDataTable(options);
})
{% block content_bottom_left %} .on('click', '.btn_tag_delete', function () {
<form id="" method="get" action="" class=" mail-search"> var $this = $(this);
<div class="input-group"> var $data_table = $('#tag_list_table').DataTable();
<select class="form-control m-b" style="width: auto"> var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
<option>{% trans 'Delete selected' %}</option> var uid = $this.data('uid');
<option>{% trans 'Update selected' %}</option> var the_url = '{% url "api-assets:asset-tag-detail" pk=99991937 %}'.replace('99991937', uid);
<option>{% trans 'Deactive selected' %}</option> objectDelete($this, name, the_url);
<option>{% trans 'Export selected' %}</option> $data_table.ajax.reload();
</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">
{% trans 'Submit' %}
</button>
</div>
</div>
</form>
{% endblock %}
</script>
{% endblock %}
\ No newline at end of file
...@@ -7,6 +7,9 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 %}
\ No newline at end of file
...@@ -27,7 +27,7 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 %}
\ No newline at end of file
{% 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 @@ ...@@ -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(){ ...@@ -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(){ ...@@ -56,6 +62,64 @@ $(document).ready(function(){
op_html: $('#actions').html() op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn_idc_delete', function () {
var $this = $(this);
var $data_table = $('#idc_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
{# TODO: reload the tale #}
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#idc_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
var the_url = "{% url 'api-assets:idc-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected idc !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'IDC Deleted.' %}";
swal("{% trans 'IDC Delete' %}", msg, "success");
$('#idc_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'IDC Deleting failed.' %}";
swal("{% trans 'IDC Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
switch (action) {
case 'delete':
doDelete();
break;
default:
break;
}
}); });
</script> </script>
{% endblock %} {% endblock %}
......
...@@ -43,35 +43,35 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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
});
}
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>'
)
}); });
</script> 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 %}
\ No newline at end of file
...@@ -26,33 +26,110 @@ ...@@ -26,33 +26,110 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-warning">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
$(document).ready(function(){ $(document).ready(function(){
var options = { var options = {
ele: $('#system_user_list_table'), ele: $('#system_user_list_table'),
columnDefs: [ columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) { {targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:system-user-detail" pk=99991937 %}">' + cellData + '</a>'; var detail_btn = '<a href="{% url "assets:system-user-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id)); $(td).html(detail_btn.replace('99991937', rowData.id));
}}, }},
{targets: 5, createdCell: function (td, cellData) { {targets: 5, createdCell: function (td, cellData) {
var innerHtml = cellData.length > 30 ? cellData.substring(0, 30) + '...': cellData; var innerHtml = cellData.length > 30 ? cellData.substring(0, 30) + '...': cellData;
$(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>'); $(td).html('<span href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</span>');
}}, }},
{targets: 6, createdCell: function (td, cellData, rowData) { {targets: 6, createdCell: function (td, cellData, rowData) {
var script_btn = '<a href="{% url "assets:system-user-update" pk=99991937 %}" class="btn btn-xs btn-primary">{% trans "Script" %}</a>'.replace('99991937', cellData); var script_btn = '<a href="{% url "assets:system-user-update" pk=99991937 %}" class="btn btn-xs btn-primary">{% trans "Script" %}</a>'.replace('99991937', cellData);
var update_btn = '<a href="{% url "assets:system-user-update" pk=99991937 %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData); var update_btn = '<a href="{% url "assets:system-user-update" pk=99991937 %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData); var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_admin_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(script_btn + update_btn + del_btn) $(td).html(script_btn + update_btn + del_btn)
}}], }}],
ajax_url: '{% url "api-assets:system-user-list" %}', ajax_url: '{% url "api-assets:system-user-list" %}',
columns: [{data: "id" }, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () { return "3"}}, columns: [{data: "id" }, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () { return "3"}},
{data: "comment" }, {data: "id" }], {data: "comment" }, {data: "id" }],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn_admin_user_delete', function () {
var $this = $(this);
var $data_table = $('#idc_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:system-user-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#system_user_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
}); });
if (id_list === []) {
return false;
}
var the_url = "{% url 'api-assets:system-user-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected System Users !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'System Users Deleted.' %}";
swal("{% trans 'System Users Delete' %}", msg, "success");
$('#system_user_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'System Users Deleting failed.' %}";
swal("{% trans 'System Users Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
{# TODO: bulk update the System Users #}
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
})
</script> </script>
{% endblock %} {% endblock %}
......
...@@ -2,16 +2,18 @@ ...@@ -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 = [ ...@@ -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
......
...@@ -16,7 +16,7 @@ from django.urls import reverse_lazy ...@@ -16,7 +16,7 @@ from django.urls import reverse_lazy
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin from django.views.generic.detail import DetailView, SingleObjectMixin
from django.shortcuts import get_object_or_404, reverse, redirect from django.shortcuts import get_object_or_404, reverse, redirect
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.views.decorators.csrf import csrf_protect, csrf_exempt from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.core.cache import cache from django.core.cache import cache
...@@ -31,803 +31,839 @@ from .hands import AdminUserRequiredMixin ...@@ -31,803 +31,839 @@ from .hands import AdminUserRequiredMixin
class AssetListView(AdminUserRequiredMixin, TemplateView): class AssetListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/asset_list.html' template_name = 'assets/asset_list.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': 'Assets', 'app': 'Assets',
'action': 'asset list', 'action': 'asset list',
'tag_list': [(i.id, i.name, i.asset_set.all().count())for i in Tag.objects.all().order_by('name')] 'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
} 'tag_list': [(i.id, i.name, i.assets.all().count())for i in Tag.objects.all().order_by('name')],
kwargs.update(context) 'tags': Tag.objects.all().order_by('name')
return super(AssetListView, self).get_context_data(**kwargs) }
kwargs.update(context)
return super(AssetListView, self).get_context_data(**kwargs)
class AssetCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView): class AssetCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView):
model = Asset model = Asset
tag_type = 'asset' tag_type = 'asset'
form_class = forms.AssetCreateForm form_class = forms.AssetCreateForm
template_name = 'assets/asset_create.html' template_name = 'assets/asset_create.html'
success_url = reverse_lazy('assets:asset-list') success_url = reverse_lazy('assets:asset-list')
def form_valid(self, form): def form_valid(self, form):
asset = form.save() asset = form.save()
asset.created_by = self.request.user.username or 'Admin' asset.created_by = self.request.user.username or 'Admin'
asset.save() asset.save()
return super(AssetCreateView, self).form_valid(form) return super(AssetCreateView, self).form_valid(form)
def form_invalid(self, form): def form_invalid(self, form):
if form.errors.get('__all__'): if form.errors.get('__all__'):
form.errors['all'] = form.errors.get('__all__') form.errors['all'] = form.errors.get('__all__')
return super(AssetCreateView, self).form_invalid(form) return super(AssetCreateView, self).form_invalid(form)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': 'Assets', 'app': 'Assets',
'action': 'Create asset', 'action': 'Create asset',
} }
kwargs.update(context) kwargs.update(context)
return super(AssetCreateView, self).get_context_data(**kwargs) return super(AssetCreateView, self).get_context_data(**kwargs)
class AssetModalCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, ListView): class AssetModalCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, ListView):
model = Asset model = Asset
form_class = forms.AssetCreateForm form_class = forms.AssetCreateForm
template_name = 'assets/asset_modal_update.html' template_name = 'assets/asset_modal_update.html'
success_url = reverse_lazy('assets:asset-list') success_url = reverse_lazy('assets:asset-list')
def get_queryset(self): def get_queryset(self):
self.queryset = super(AssetModalCreateView,self).get_queryset() self.queryset = super(AssetModalCreateView,self).get_queryset()
self.s = self.request.GET.get('plain_id_lists') self.s = self.request.GET.get('plain_id_lists')
if "," in str(self.s): if "," in str(self.s):
self.plain_id_lists = [int(x) for x in self.s.split(',')] self.plain_id_lists = [int(x) for x in self.s.split(',')]
else: else:
self.plain_id_lists = [self.s] self.plain_id_lists = [self.s]
return self.queryset return self.queryset
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
asset_on_list = Asset.objects.filter(id__in = self.plain_id_lists) asset_on_list = Asset.objects.filter(id__in = self.plain_id_lists)
context = { context = {
'app': 'Assets', 'app': 'Assets',
'action': 'Bulk Update asset', 'action': 'Bulk Update asset',
'assets_on_list': asset_on_list, 'assets_on_list': asset_on_list,
'assets_count': len(asset_on_list), 'assets_count': len(asset_on_list),
'plain_id_lists':self.s, 'plain_id_lists':self.s,
} }
kwargs.update(context) kwargs.update(context)
return super(AssetModalCreateView, self).get_context_data(**kwargs) return super(AssetModalCreateView, self).get_context_data(**kwargs)
class AssetUpdateView(AdminUserRequiredMixin, UpdateAssetTagsMiXin, UpdateView): class AssetUpdateView(AdminUserRequiredMixin, UpdateAssetTagsMiXin, UpdateView):
model = Asset model = Asset
form_class = forms.AssetCreateForm form_class = forms.AssetCreateForm
template_name = 'assets/asset_update.html' template_name = 'assets/asset_update.html'
success_url = reverse_lazy('assets:asset-list') success_url = reverse_lazy('assets:asset-list')
new_form = '' new_form = ''
assets_ids = '' assets_ids = ''
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
default_keys = [ default_keys = [
'csrfmiddlewaretoken', 'csrfmiddlewaretoken',
'assets_ids', 'assets_ids',
'ip', 'ip',
'number', 'number',
'hostname', 'hostname',
'system_users', 'system_users',
'admin_user', 'admin_user',
] ]
self.assets_ids = self.request.POST.getlist('assets_ids') self.assets_ids = self.request.POST.getlist('assets_ids')
self.new_form = self.request.POST.copy() self.new_form = self.request.POST.copy()
for i in default_keys: for i in default_keys:
if self.new_form.has_key(i): if self.new_form.has_key(i):
self.new_form.pop(i) self.new_form.pop(i)
return super(AssetUpdateView, self).post(request, *args, **kwargs) return super(AssetUpdateView, self).post(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': 'Assets', 'app': 'Assets',
'action': 'Update asset', 'action': 'Update asset',
} }
kwargs.update(context) kwargs.update(context)
return super(AssetUpdateView, self).get_context_data(**kwargs) return super(AssetUpdateView, self).get_context_data(**kwargs)
def form_invalid(self, form): def form_invalid(self, form):
print(form.errors) print(form.errors)
return super(AssetUpdateView, self).form_invalid(form) return super(AssetUpdateView, self).form_invalid(form)
def form_valid(self, form): def form_valid(self, form):
asset = form.save(commit=False) asset = form.save(commit=False)
def prn_obj_key(obj_form): def prn_obj_key(obj_form):
return obj_form.clean().keys() return obj_form.clean().keys()
for i in prn_obj_key(form): for i in prn_obj_key(form):
if i not in self.new_form.keys(): if i not in self.new_form.keys():
print i print i
#delattr(asset, '"%s" % i') #delattr(asset, '"%s" % i')
#del asset.i #del asset.i
asset.save() asset.save()
asset.id = 27 asset.id = 27
# asset.created_by = self.request.user.username or 'Admin' # asset.created_by = self.request.user.username or 'Admin'
asset.save() asset.save()
asset.id = 28 asset.id = 28
asset.save() asset.save()
return super(AssetUpdateView, self).form_valid(form) return super(AssetUpdateView, self).form_valid(form)
class AssetDeleteView(DeleteView): class AssetDeleteView(DeleteView):
model = Asset model = Asset
template_name = 'assets/delete_confirm.html' template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:asset-list') success_url = reverse_lazy('assets:asset-list')
class AssetDetailView(DetailView): class AssetDetailView(DetailView):
model = Asset model = Asset
context_object_name = 'asset' context_object_name = 'asset'
template_name = 'assets/asset_detail.html' template_name = 'assets/asset_detail.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
asset_groups = self.object.groups.all() asset_groups = self.object.groups.all()
system_users = self.object.system_users.all() system_users = self.object.system_users.all()
context = { context = {
'app': 'Assets', 'app': 'Assets',
'action': 'Asset detail', 'action': 'Asset detail',
'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all() 'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all()
if asset_group not in asset_groups], if asset_group not in asset_groups],
'asset_groups': asset_groups, 'asset_groups': asset_groups,
'system_users_remain': [system_user for system_user in SystemUser.objects.all() 'system_users_remain': [system_user for system_user in SystemUser.objects.all()
if system_user not in system_users], if system_user not in system_users],
'system_users': system_users, 'system_users': system_users,
} }
kwargs.update(context) kwargs.update(context)
return super(AssetDetailView, self).get_context_data(**kwargs) return super(AssetDetailView, self).get_context_data(**kwargs)
class AssetModalListView(AdminUserRequiredMixin, ListView): class AssetModalListView(AdminUserRequiredMixin, ListView):
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
model = Asset model = Asset
context_object_name = 'asset_modal_list' context_object_name = 'asset_modal_list'
template_name = 'assets/asset_modal_list.html' template_name = 'assets/asset_modal_list.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
group_id = self.request.GET.get('group_id') group_id = self.request.GET.get('group_id')
tag_id = self.request.GET.get('tag_id') tag_id = self.request.GET.get('tag_id')
plain_id_lists = self.request.GET.get('plain_id_lists') plain_id_lists = self.request.GET.get('plain_id_lists')
self.s = self.request.GET.get('plain_id_lists') self.s = self.request.GET.get('plain_id_lists')
if "," in str(self.s): if "," in str(self.s):
self.plain_id_lists = [int(x) for x in self.s.split(',')] self.plain_id_lists = [int(x) for x in self.s.split(',')]
else: else:
self.plain_id_lists = [self.s] self.plain_id_lists = [self.s]
if plain_id_lists: if plain_id_lists:
if "," in str(self.s): if "," in str(self.s):
plain_id_lists = [int(x) for x in self.s.split(',')] plain_id_lists = [int(x) for x in self.s.split(',')]
else: else:
plain_id_lists = [int(self.s)] plain_id_lists = [int(self.s)]
context = { context = {
'all_assets' :plain_id_lists 'all_assets' :plain_id_lists
} }
kwargs.update(context) kwargs.update(context)
if group_id: if group_id:
group = AssetGroup.objects.get(id=group_id) group = AssetGroup.objects.get(id=group_id)
context = { context = {
'all_assets': [x.id for x in group.assets.all()] 'all_assets': [x.id for x in group.assets.all()]
} }
kwargs.update(context) kwargs.update(context)
if tag_id: if tag_id:
tag = Tag.objects.get(id=tag_id) tag = Tag.objects.get(id=tag_id)
context = { context = {
'all_assets': [x.id for x in tag.asset_set.all()] 'all_assets': [x.id for x in tag.asset_set.all()]
} }
kwargs.update(context) kwargs.update(context)
return super(AssetModalListView, self).get_context_data(**kwargs) return super(AssetModalListView, self).get_context_data(**kwargs)
class AssetGroupCreateView(AdminUserRequiredMixin, CreateView): class AssetGroupCreateView(AdminUserRequiredMixin, CreateView):
model = AssetGroup model = AssetGroup
form_class = forms.AssetGroupForm form_class = forms.AssetGroupForm
template_name = 'assets/asset_group_create.html' template_name = 'assets/asset_group_create.html'
success_url = reverse_lazy('assets:asset-group-list') success_url = reverse_lazy('assets:asset-group-list')
#ordering = '-id' #ordering = '-id'
# Todo: Asset group create template select assets so hard, need be resolve next # Todo: Asset group create template select assets so hard, need be resolve next
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('Create asset group'), 'action': _('Create asset group'),
'assets_count': 0, 'assets_count': 0,
} }
kwargs.update(context) kwargs.update(context)
return super(AssetGroupCreateView, self).get_context_data(**kwargs) return super(AssetGroupCreateView, self).get_context_data(**kwargs)
def form_valid(self, form): def form_valid(self, form):
asset_group = form.save() asset_group = form.save()
assets_id_list = self.request.POST.getlist('assets', []) assets_id_list = self.request.POST.getlist('assets', [])
assets = [get_object_or_404(Asset, id=int(asset_id)) for asset_id in assets_id_list] assets = [get_object_or_404(Asset, id=int(asset_id)) for asset_id in assets_id_list]
asset_group.created_by = self.request.user.username or 'Admin' asset_group.created_by = self.request.user.username or 'Admin'
asset_group.assets.add(*tuple(assets)) asset_group.assets.add(*tuple(assets))
asset_group.save() asset_group.save()
return super(AssetGroupCreateView, self).form_valid(form) return super(AssetGroupCreateView, self).form_valid(form)
class AssetGroupListView(AdminUserRequiredMixin, TemplateView): class AssetGroupListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/asset_group_list.html' template_name = 'assets/asset_group_list.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('Asset group list'), 'action': _('Asset group list'),
'keyword': self.request.GET.get('keyword', '') 'assets': Asset.objects.all(),
} 'system_users': SystemUser.objects.all(),
kwargs.update(context) 'keyword': self.request.GET.get('keyword', '')
return super(AssetGroupListView, self).get_context_data(**kwargs) }
kwargs.update(context)
return super(AssetGroupListView, self).get_context_data(**kwargs)
class AssetGroupDetailView(AdminUserRequiredMixin, DetailView): class AssetGroupDetailView(AdminUserRequiredMixin, DetailView):
model = AssetGroup model = AssetGroup
template_name = 'assets/asset_group_detail.html' template_name = 'assets/asset_group_detail.html'
context_object_name = 'asset_group' context_object_name = 'asset_group'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all()) assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
system_users = self.object.system_users.all() system_users = self.object.system_users.all()
system_users_remain = SystemUser.objects.exclude(id__in=system_users) system_users_remain = SystemUser.objects.exclude(id__in=system_users)
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('Asset group detail'), 'action': _('Asset group detail'),
'assets_remain': assets_remain, 'assets_remain': assets_remain,
'system_users': system_users, 'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain],
'system_users_remain': system_users_remain, 'system_users': system_users,
} 'system_users_remain': system_users_remain,
kwargs.update(context) }
return super(AssetGroupDetailView, self).get_context_data(**kwargs) kwargs.update(context)
return super(AssetGroupDetailView, self).get_context_data(**kwargs)
class AssetGroupUpdateView(AdminUserRequiredMixin, UpdateView): class AssetGroupUpdateView(AdminUserRequiredMixin, UpdateView):
model = AssetGroup model = AssetGroup
form_class = forms.AssetGroupForm form_class = forms.AssetGroupForm
template_name = 'assets/asset_group_create.html' template_name = 'assets/asset_group_create.html'
success_url = reverse_lazy('assets:asset-group-list') success_url = reverse_lazy('assets:asset-group-list')
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=AssetGroup.objects.all()) self.object = self.get_object(queryset=AssetGroup.objects.all())
return super(AssetGroupUpdateView, self).get(request, *args, **kwargs) return super(AssetGroupUpdateView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
assets_all = self.object.assets.all() assets_all = self.object.assets.all()
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('Create asset group'), 'action': _('Create asset group'),
'assets_on_list': assets_all, 'assets_on_list': assets_all,
'assets_count': len(assets_all), 'assets_count': len(assets_all),
'group_id':self.object.id, 'group_id':self.object.id,
} }
kwargs.update(context) kwargs.update(context)
return super(AssetGroupUpdateView, self).get_context_data(**kwargs) return super(AssetGroupUpdateView, self).get_context_data(**kwargs)
class AssetGroupDeleteView(AdminUserRequiredMixin, DeleteView): class AssetGroupDeleteView(AdminUserRequiredMixin, DeleteView):
template_name = 'assets/delete_confirm.html' template_name = 'assets/delete_confirm.html'
model = AssetGroup model = AssetGroup
success_url = reverse_lazy('assets:asset-group-list') success_url = reverse_lazy('assets:asset-group-list')
class IDCListView(AdminUserRequiredMixin, TemplateView): class IDCListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/idc_list.html' template_name = 'assets/idc_list.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('IDC list'), 'action': _('IDC list'),
# 'keyword': self.request.GET.get('keyword', '') # 'keyword': self.request.GET.get('keyword', '')
} }
kwargs.update(context) kwargs.update(context)
return super(IDCListView, self).get_context_data(**kwargs) return super(IDCListView, self).get_context_data(**kwargs)
class IDCCreateView(AdminUserRequiredMixin, CreateView): class IDCCreateView(AdminUserRequiredMixin, CreateView):
model = IDC model = IDC
form_class = forms.IDCForm form_class = forms.IDCForm
template_name = 'assets/idc_create_update.html' template_name = 'assets/idc_create_update.html'
success_url = reverse_lazy('assets:idc-list') success_url = reverse_lazy('assets:idc-list')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('assets'), 'app': _('assets'),
'action': _('Create IDC'), 'action': _('Create IDC'),
} }
kwargs.update(context) kwargs.update(context)
return super(IDCCreateView, self).get_context_data(**kwargs) return super(IDCCreateView, self).get_context_data(**kwargs)
def form_valid(self, form): def form_valid(self, form):
IDC = form.save(commit=False) IDC = form.save(commit=False)
IDC.created_by = self.request.user.username or 'System' IDC.created_by = self.request.user.username or 'System'
IDC.save() IDC.save()
# IDC_add_success_next(user) # IDC_add_success_next(user)
return super(IDCCreateView, self).form_valid(form) return super(IDCCreateView, self).form_valid(form)
class IDCUpdateView(AdminUserRequiredMixin, UpdateView): class IDCUpdateView(AdminUserRequiredMixin, UpdateView):
model = IDC model = IDC
form_class = forms.IDCForm form_class = forms.IDCForm
template_name = 'assets/idc_create_update.html' template_name = 'assets/idc_create_update.html'
context_object_name = 'idc' context_object_name = 'idc'
success_url = reverse_lazy('assets:idc-list') success_url = reverse_lazy('assets:idc-list')
def form_valid(self, form): def form_valid(self, form):
idc = form.save(commit=False) idc = form.save(commit=False)
idc.save() idc.save()
return super(IDCUpdateView, self).form_valid(form) return super(IDCUpdateView, self).form_valid(form)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('assets'), 'app': _('assets'),
'action': _('Update IDC'), 'action': _('Update IDC'),
} }
kwargs.update(context) kwargs.update(context)
return super(IDCUpdateView, self).get_context_data(**kwargs) return super(IDCUpdateView, self).get_context_data(**kwargs)
class IDCDetailView(AdminUserRequiredMixin, DetailView): class IDCDetailView(AdminUserRequiredMixin, DetailView):
model = IDC model = IDC
template_name = 'assets/idc_detail.html' template_name = 'assets/idc_detail.html'
context_object_name = 'idc' context_object_name = 'idc'
class IDCAssetsView(AdminUserRequiredMixin, DetailView): class IDCAssetsView(AdminUserRequiredMixin, DetailView):
model = IDC model = IDC
template_name = 'assets/idc_assets.html' template_name = 'assets/idc_assets.html'
context_object_name = 'idc' context_object_name = 'idc'
def get_context_data(self, **kwargs):
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
context = {
'app': _('Assets'),
'action': _('Asset detail'),
'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
'tags': Tag.objects.all(),
'assets_remain': assets_remain,
'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain],
}
kwargs.update(context)
return super(IDCAssetsView, self).get_context_data(**kwargs)
class IDCDeleteView(AdminUserRequiredMixin, DeleteView): class IDCDeleteView(AdminUserRequiredMixin, DeleteView):
model = IDC model = IDC
template_name = 'assets/delete_confirm.html' template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:idc-list') success_url = reverse_lazy('assets:idc-list')
class AdminUserListView(AdminUserRequiredMixin, TemplateView): class AdminUserListView(AdminUserRequiredMixin, TemplateView):
model = AdminUser model = AdminUser
# paginate_by = settings.CONFIG.DISPLAY_PER_PAGE # paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
# context_object_name = 'admin_user_list' # context_object_name = 'admin_user_list'
template_name = 'assets/admin_user_list.html' template_name = 'assets/admin_user_list.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('Admin user list'), 'action': _('Admin user list'),
# 'keyword': self.request.GET.get('keyword', '') # 'keyword': self.request.GET.get('keyword', '')
} }
kwargs.update(context) kwargs.update(context)
return super(AdminUserListView, self).get_context_data(**kwargs) return super(AdminUserListView, self).get_context_data(**kwargs)
# def get_queryset(self): # def get_queryset(self):
# Todo: Default order by lose asset connection num # Todo: Default order by lose asset connection num
# self.queryset = super(AdminUserListView, self).get_queryset() # self.queryset = super(AdminUserListView, self).get_queryset()
# self.keyword = keyword = self.request.GET.get('keyword', '') # self.keyword = keyword = self.request.GET.get('keyword', '')
# self.sort = sort = self.request.GET.get('sort', '-date_created') # self.sort = sort = self.request.GET.get('sort', '-date_created')
# #
# if keyword: # if keyword:
# self.queryset = self.queryset.filter(Q(name__icontains=keyword) | # self.queryset = self.queryset.filter(Q(name__icontains=keyword) |
# Q(comment__icontains=keyword)) # Q(comment__icontains=keyword))
# #
# if sort: # if sort:
# self.queryset = self.queryset.order_by(sort) # self.queryset = self.queryset.order_by(sort)
# return self.queryset # return self.queryset
class AdminUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView): class AdminUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = AdminUser model = AdminUser
form_class = forms.AdminUserForm form_class = forms.AdminUserForm
template_name = 'assets/admin_user_create_update.html' template_name = 'assets/admin_user_create_update.html'
success_url = reverse_lazy('assets:admin-user-list') success_url = reverse_lazy('assets:admin-user-list')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': 'assets', 'app': 'assets',
'action': 'Create admin user' 'action': 'Create admin user'
} }
kwargs.update(context) kwargs.update(context)
return super(AdminUserCreateView, self).get_context_data(**kwargs) return super(AdminUserCreateView, self).get_context_data(**kwargs)
def get_success_message(self, cleaned_data): def get_success_message(self, cleaned_data):
success_message = _('Create admin user <a href="%s">%s</a> successfully.' % success_message = _('Create admin user <a href="%s">%s</a> successfully.' %
( (
reverse_lazy('assets:admin-user-detail', kwargs={'pk': self.object.pk}), reverse_lazy('assets:admin-user-detail', kwargs={'pk': self.object.pk}),
self.object.name, self.object.name,
)) ))
return success_message return success_message
def form_invalid(self, form): def form_invalid(self, form):
return super(AdminUserCreateView, self).form_invalid(form) return super(AdminUserCreateView, self).form_invalid(form)
class AdminUserUpdateView(AdminUserRequiredMixin, UpdateView): class AdminUserUpdateView(AdminUserRequiredMixin, UpdateView):
model = AdminUser model = AdminUser
form_class = forms.AdminUserForm form_class = forms.AdminUserForm
template_name = 'assets/admin_user_create_update.html' template_name = 'assets/admin_user_create_update.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': 'assets', 'app': 'assets',
'action': 'Update admin user' 'action': 'Update admin user'
} }
kwargs.update(context) kwargs.update(context)
return super(AdminUserUpdateView, self).get_context_data(**kwargs) return super(AdminUserUpdateView, self).get_context_data(**kwargs)
def get_success_url(self): def get_success_url(self):
success_url = reverse_lazy('assets:admin-user-detail', pk=self.object.pk) success_url = reverse_lazy('assets:admin-user-detail', pk=self.object.pk)
return success_url return success_url
class AdminUserDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView): class AdminUserDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
template_name = 'assets/admin_user_detail.html' template_name = 'assets/admin_user_detail.html'
context_object_name = 'admin_user' context_object_name = 'admin_user'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=AdminUser.objects.all()) self.object = self.get_object(queryset=AdminUser.objects.all())
return super(AdminUserDetailView, self).get(request, *args, **kwargs) return super(AdminUserDetailView, self).get(request, *args, **kwargs)
# Todo: queryset default order by connectivity, need ops support # Todo: queryset default order by connectivity, need ops support
def get_queryset(self): def get_queryset(self):
return self.object.assets.all() return self.object.assets.all()
def get_context_data(self, **kwargs): # def get_asset_groups(self):
context = { # return self.object.asset_groups.all()
'app': 'assets',
'action': 'Admin user detail' def get_context_data(self, **kwargs):
} asset_groups = AssetGroup.objects.all()
kwargs.update(context) assets = self.get_queryset()
return super(AdminUserDetailView, self).get_context_data(**kwargs) context = {
'app': 'assets',
'action': 'Admin user detail',
'assets_remain': [asset for asset in Asset.objects.all() if asset not in assets],
'asset_groups': asset_groups,
# 'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all()
# if asset_group not in asset_groups]
}
kwargs.update(context)
return super(AdminUserDetailView, self).get_context_data(**kwargs)
class AdminUserDeleteView(AdminUserRequiredMixin, DeleteView): class AdminUserDeleteView(AdminUserRequiredMixin, DeleteView):
model = AdminUser model = AdminUser
template_name = 'assets/delete_confirm.html' template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:admin-user-list') success_url = reverse_lazy('assets:admin-user-list')
class SystemUserListView(AdminUserRequiredMixin, TemplateView): class SystemUserListView(AdminUserRequiredMixin, TemplateView):
template_name = 'assets/system_user_list.html' template_name = 'assets/system_user_list.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('System user list'), 'action': _('System user list'),
} }
kwargs.update(context) kwargs.update(context)
return super(SystemUserListView, self).get_context_data(**kwargs) return super(SystemUserListView, self).get_context_data(**kwargs)
class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView): class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = SystemUser model = SystemUser
form_class = forms.SystemUserForm form_class = forms.SystemUserForm
template_name = 'assets/system_user_create_update.html' template_name = 'assets/system_user_create_update.html'
success_url = reverse_lazy('assets:system-user-list') success_url = reverse_lazy('assets:system-user-list')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('Create system user'), 'action': _('Create system user'),
} }
kwargs.update(context) kwargs.update(context)
return super(SystemUserCreateView, self).get_context_data(**kwargs) return super(SystemUserCreateView, self).get_context_data(**kwargs)
def get_success_message(self, cleaned_data): def get_success_message(self, cleaned_data):
success_message = _('Create system user <a href="%s">%s</a> successfully.' % success_message = _('Create system user <a href="%s">%s</a> successfully.' %
( (
reverse_lazy('assets:system-user-detail', kwargs={'pk': self.object.pk}), reverse_lazy('assets:system-user-detail', kwargs={'pk': self.object.pk}),
self.object.name, self.object.name,
)) ))
return success_message return success_message
class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView): class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView):
model = SystemUser model = SystemUser
form_class = forms.SystemUserForm form_class = forms.SystemUserForm
template_name = 'assets/system_user_create_update.html' template_name = 'assets/system_user_create_update.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('Update system user') 'action': _('Update system user')
} }
kwargs.update(context) kwargs.update(context)
return super(SystemUserUpdateView, self).get_context_data(**kwargs) return super(SystemUserUpdateView, self).get_context_data(**kwargs)
def get_success_url(self): def get_success_url(self):
success_url = reverse_lazy('assets:system-user-detail', kwargs={'pk': self.object.pk}) success_url = reverse_lazy('assets:system-user-detail', kwargs={'pk': self.object.pk})
return success_url return success_url
class SystemUserDetailView(AdminUserRequiredMixin, DetailView): class SystemUserDetailView(AdminUserRequiredMixin, DetailView):
template_name = 'assets/system_user_detail.html' template_name = 'assets/system_user_detail.html'
context_object_name = 'system_user' context_object_name = 'system_user'
model = SystemUser model = SystemUser
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('System user detail') 'action': _('System user detail')
} }
kwargs.update(context) kwargs.update(context)
return super(SystemUserDetailView, self).get_context_data(**kwargs) return super(SystemUserDetailView, self).get_context_data(**kwargs)
class SystemUserDeleteView(AdminUserRequiredMixin, DeleteView): class SystemUserDeleteView(AdminUserRequiredMixin, DeleteView):
model = SystemUser model = SystemUser
template_name = 'assets/delete_confirm.html' template_name = 'assets/delete_confirm.html'
success_url = reverse_lazy('assets:system-user-list') success_url = reverse_lazy('assets:system-user-list')
class SystemUserAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView): class SystemUserAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
template_name = 'assets/system_user_asset.html' template_name = 'assets/system_user_asset.html'
context_object_name = 'system_user' context_object_name = 'system_user'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=SystemUser.objects.all()) self.object = self.get_object(queryset=SystemUser.objects.all())
return super(SystemUserAssetView, self).get(request, *args, **kwargs) return super(SystemUserAssetView, self).get(request, *args, **kwargs)
def get_asset_groups(self): def get_asset_groups(self):
return self.object.asset_groups.all() return self.object.asset_groups.all()
# Todo: queryset default order by connectivity, need ops support # Todo: queryset default order by connectivity, need ops support
def get_queryset(self): def get_queryset(self):
return list(self.object.get_assets()) return list(self.object.get_assets())
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
asset_groups = self.get_asset_groups() asset_groups = self.get_asset_groups()
assets = self.get_queryset() assets = self.get_queryset()
context = { context = {
'app': 'assets', 'app': 'assets',
'action': 'System user asset', 'action': 'System user asset',
'assets_remain': [asset for asset in Asset.objects.all() if asset not in assets], 'assets_remain': [asset for asset in Asset.objects.all() if asset not in assets],
'asset_groups': asset_groups, 'asset_groups': asset_groups,
'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all() 'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all()
if asset_group not in asset_groups] if asset_group not in asset_groups]
} }
kwargs.update(context) kwargs.update(context)
return super(SystemUserAssetView, self).get_context_data(**kwargs) return super(SystemUserAssetView, self).get_context_data(**kwargs)
class TagView(ListView): class TagView(ListView):
context_object_name = 'asset_list' context_object_name = 'asset_list'
template_name = 'assets/asset_list.html' template_name = 'assets/asset_list.html'
def get_queryset(self): def get_queryset(self):
asset_list = Asset.objects.filter(tags=self.kwargs['tag_id']) asset_list = Asset.objects.filter(tags=self.kwargs['tag_id'])
return asset_list return asset_list
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
kwargs['app'] = 'Assets' kwargs['app'] = 'Assets'
kwargs['action']='asset list' kwargs['action']='asset list'
kwargs['tag_list'] = [(i.id,i.name,i.asset_set.all().count() )for i in Tag.objects.all().order_by('name')] kwargs['tag_list'] = [(i.id,i.name,i.asset_set.all().count() )for i in Tag.objects.all().order_by('name')]
kwargs['tag_id'] = self.kwargs['tag_id'] kwargs['tag_id'] = self.kwargs['tag_id']
return super(TagView, self).get_context_data(**kwargs) return super(TagView, self).get_context_data(**kwargs)
class TagsListView(AdminUserRequiredMixin, ListView): class TagsListView(AdminUserRequiredMixin, ListView):
model = Tag model = Tag
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
context_object_name = 'asset_tags_list' context_object_name = 'asset_tags_list'
template_name = 'assets/asset_tags_list.html' template_name = 'assets/asset_tags_list.html'
ordering = '-id' ordering = '-id'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Tag'), 'app': _('Tag'),
'action': _('Asset Tags list'), 'action': _('Asset Tags list'),
'keyword': self.request.GET.get('keyword', '') 'keyword': self.request.GET.get('keyword', '')
} }
kwargs.update(context) kwargs.update(context)
return super(TagsListView, self).get_context_data(**kwargs) return super(TagsListView, self).get_context_data(**kwargs)
class AssetTagCreateView(AdminUserRequiredMixin, CreateView): class AssetTagCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView):
model = Tag model = Tag
form_class = forms.AssetTagForm form_class = forms.AssetTagForm
template_name = 'assets/asset_tag_create.html' template_name = 'assets/asset_tag_create.html'
success_url = reverse_lazy('assets:asset-tag-list') success_url = reverse_lazy('assets:asset-tag-list')
#ordering = '-id' #ordering = '-id'
# Todo: Asset group create template select assets so hard, need be resolve next # Todo: Asset group create template select assets so hard, need be resolve next
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Tag'), 'app': _('Tag'),
'action': _('Asset Tags list'), 'action': _('Asset Tags list'),
'assets_count': 0, 'assets_count': 0,
} }
kwargs.update(context) kwargs.update(context)
return super(AssetTagCreateView, self).get_context_data(**kwargs) return super(AssetTagCreateView, self).get_context_data(**kwargs)
def form_valid(self, form): def form_valid(self, form):
asset_tag = form.save() asset_tag = form.save()
assets_id_list = self.request.POST.getlist('assets', []) assets_id_list = self.request.POST.getlist('assets', [])
assets = [get_object_or_404(Asset, id=int(asset_id)) for asset_id in assets_id_list] assets = [get_object_or_404(Asset, id=int(asset_id)) for asset_id in assets_id_list]
asset_tag.created_by = self.request.user.username or 'Admin' asset_tag.created_by = self.request.user.username or 'Admin'
asset_tag.asset_set.add(*tuple(assets)) asset_tag.assets.add(*tuple(assets))
asset_tag.save() asset_tag.save()
return super(AssetTagCreateView, self).form_valid(form) return super(AssetTagCreateView, self).form_valid(form)
class AssetTagDetailView(SingleObjectMixin, AdminUserRequiredMixin, ListView): class AssetTagDetailView(SingleObjectMixin, AdminUserRequiredMixin, ListView):
template_name = 'assets/asset_tag_detail.html' template_name = 'assets/asset_tag_detail.html'
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=Tag.objects.all()) self.object = self.get_object(queryset=Tag.objects.all())
return super(AssetTagDetailView, self).get(request, *args, **kwargs) return super(AssetTagDetailView, self).get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
return self.object.asset_set.all() return self.object.assets.all()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
'app': _('Tag'), context = {
'action': _('Asset Tags detail'), 'app': _('Tag'),
'asset_tag': self.object, 'action': _('Asset Tags detail'),
} 'asset_tag': self.object,
kwargs.update(context) 'assets_remain': assets_remain,
return super(AssetTagDetailView, self).get_context_data(**kwargs) 'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain]
}
kwargs.update(context)
return super(AssetTagDetailView, self).get_context_data(**kwargs)
class AssetTagUpdateView(AdminUserRequiredMixin, UpdateView): class AssetTagUpdateView(AdminUserRequiredMixin, UpdateView):
model = Tag model = Tag
form_class = forms.AssetTagForm form_class = forms.AssetTagForm
template_name = 'assets/asset_tag_create.html' template_name = 'assets/asset_tag_create.html'
success_url = reverse_lazy('assets:asset-tag-list') success_url = reverse_lazy('assets:asset-tag-list')
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=Tag.objects.all()) self.object = self.get_object(queryset=Tag.objects.all())
return super(AssetTagUpdateView, self).get(request, *args, **kwargs) return super(AssetTagUpdateView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
assets_all = self.object.asset_set.all() assets_all = self.object.assets.all()
context = { context = {
'app': _('Tag'), 'app': _('Tag'),
'action': _('Asset Tags detail'), 'action': _('Asset Tags detail'),
'assets_count': len(assets_all), 'assets_count': len(assets_all),
'assets_on_list': assets_all, 'assets_on_list': assets_all,
'tag_id':self.object.id, 'tag_id':self.object.id,
} }
kwargs.update(context) kwargs.update(context)
return super(AssetTagUpdateView, self).get_context_data(**kwargs) return super(AssetTagUpdateView, self).get_context_data(**kwargs)
class AssetTagDeleteView(AdminUserRequiredMixin, DeleteView): class AssetTagDeleteView(AdminUserRequiredMixin, DeleteView):
template_name = 'assets/delete_confirm.html' template_name = 'assets/delete_confirm.html'
model = Tag model = Tag
success_url = reverse_lazy('assets:asset-tag-list') success_url = reverse_lazy('assets:asset-tag-list')
@method_decorator(csrf_exempt, name='dispatch') @method_decorator(csrf_exempt, name='dispatch')
class AssetExportView(View): class AssetExportView(View):
@staticmethod @staticmethod
def get_asset_attr(asset, attr): def get_asset_attr(asset, attr):
if attr in ['admin_user', 'idc']: if attr in ['admin_user', 'idc']:
return getattr(asset, attr).name return getattr(asset, attr)
elif attr in ['status', 'type', 'env']: # elif attr in ['status', 'type', 'env']:
return getattr(asset, 'get_{}_display'.format(attr))() # return getattr(asset, 'get_{}_display'.format(attr))
else: else:
return getattr(asset, attr) return getattr(asset, attr)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
spm = request.GET.get('spm', '') spm = request.GET.get('spm', '')
assets_id = cache.get(spm) assets_id = cache.get(spm)
if not assets_id and not isinstance(assets_id, list): if not assets_id and not isinstance(assets_id, list):
return HttpResponse('May be expired', status=404) return HttpResponse('May be expired', status=404)
assets = Asset.objects.filter(id__in=assets_id) assets = Asset.objects.filter(id__in=assets_id)
wb = Workbook() wb = Workbook()
ws = wb.active ws = wb.active
ws.title = 'Asset' ws.title = 'Asset'
header = ['hostname', 'ip', 'port', 'admin_user', 'idc', 'cpu', 'memory', 'disk', header = ['hostname', 'ip', 'port', 'admin_user', 'idc', 'cpu', 'memory', 'disk',
'mac_address', 'other_ip', 'remote_card_ip', 'os', 'cabinet_no', 'mac_address', 'other_ip', 'remote_card_ip', 'os', 'cabinet_no',
'cabinet_pos', 'number', 'status', 'type', 'env', 'sn', 'comment'] 'cabinet_pos', 'number', 'status', 'type', 'env', 'sn', 'comment']
ws.append(header) ws.append(header)
for asset in assets: for asset in assets:
ws.append([self.get_asset_attr(asset, attr) for attr in header]) print [self.get_asset_attr(asset, attr) for attr in header]
ws.append([self.get_asset_attr(asset, attr) for attr in header])
filename = 'assets-{}.xlsx'.format(timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S'))
response = HttpResponse(save_virtual_workbook(wb), content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="%s"' % filename filename = 'assets-{}.xlsx'.format(timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S'))
return response response = HttpResponse(save_virtual_workbook(wb), content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="%s"' % filename
def post(self, request, *args, **kwargs): return response
try:
assets_id = json.loads(request.body).get('assets_id', []) def post(self, request, *args, **kwargs):
print(assets_id) try:
except ValueError: assets_id = json.loads(request.body).get('assets_id', [])
return HttpResponse('Json object not valid', status=400) except ValueError:
spm = uuid.uuid4().get_hex() return HttpResponse('Json object not valid', status=400)
cache.set(spm, assets_id, 300) spm = uuid.uuid4().get_hex()
url = reverse('assets:asset-export') + '?spm=%s' % spm cache.set(spm, assets_id, 300)
return JsonResponse({'redirect': url}) url = reverse('assets:asset-export') + '?spm=%s' % spm
print url
return HttpResponse({'redirect': url})
class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView): class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
form_class = forms.FileForm form_class = forms.FileForm
def form_valid(self, form): def form_valid(self, form):
try: try:
wb = load_workbook(form.cleaned_data['file']) wb = load_workbook(form.cleaned_data['file'])
ws = wb.get_active_sheet() ws = wb.get_active_sheet()
except Exception as e: except Exception as e:
print(e) print(e)
data = {'valid': False, 'msg': 'Not a valid Excel file'} data = {'valid': False, 'msg': 'Not a valid Excel file'}
return self.render_json_response(data) return self.render_json_response(data)
rows = ws.rows rows = ws.rows
header_all = ['hostname', 'ip', 'port', 'admin_user', 'idc', 'cpu', 'memory', 'disk', header_all = ['hostname', 'ip', 'port', 'admin_user', 'idc', 'cpu', 'memory', 'disk',
'mac_address', 'other_ip', 'remote_card_ip', 'os', 'cabinet_no', 'mac_address', 'other_ip', 'remote_card_ip', 'os', 'cabinet_no',
'cabinet_pos', 'number', 'status', 'type', 'env', 'sn', 'comment'] 'cabinet_pos', 'number', 'status', 'type', 'env', 'sn', 'comment']
header_min = ['hostname', 'ip', 'port', 'admin_user', 'comment'] header_min = ['hostname', 'ip', 'port', 'admin_user', 'comment']
header = [col.value for col in next(rows)] header = [col.value for col in next(rows)]
if not set(header).issubset(set(header_all)) and not set(header).issuperset(set(header_min)): if not set(header).issubset(set(header_all)) and not set(header).issuperset(set(header_min)):
data = {'valid': False, 'msg': 'Must be same format as template or export file'} data = {'valid': False, 'msg': 'Must be same format as template or export file'}
return self.render_json_response(data) return self.render_json_response(data)
created = [] created = []
updated = [] updated = []
failed = [] failed = []
for row in rows: for row in rows:
asset_dict = dict(zip(header, [col.value for col in row])) asset_dict = dict(zip(header, [col.value for col in row]))
if asset_dict.get('admin_user', None): if asset_dict.get('admin_user', None):
admin_user = get_object_or_none(AdminUser, name=asset_dict['admin_user']) admin_user = get_object_or_none(AdminUser, name=asset_dict['admin_user'])
asset_dict['admin_user'] = admin_user asset_dict['admin_user'] = admin_user
if asset_dict.get('idc'): if asset_dict.get('idc'):
idc = get_object_or_none(IDC, name=asset_dict['idc']) idc = get_object_or_none(IDC, name=asset_dict['idc'])
asset_dict['idc'] = idc asset_dict['idc'] = idc
if asset_dict.get('type'): if asset_dict.get('type'):
asset_display_type_map = dict(zip(dict(Asset.TYPE_CHOICES).values(), dict(Asset.TYPE_CHOICES).keys())) asset_display_type_map = dict(zip(dict(Asset.TYPE_CHOICES).values(), dict(Asset.TYPE_CHOICES).keys()))
asset_type = asset_display_type_map.get(asset_dict['type'], 'Server') asset_type = asset_display_type_map.get(asset_dict['type'], 'Server')
asset_dict['type'] = asset_type asset_dict['type'] = asset_type
if asset_dict.get('status'): if asset_dict.get('status'):
asset_display_status_map = dict(zip(dict(Asset.STATUS_CHOICES).values(), asset_display_status_map = dict(zip(dict(Asset.STATUS_CHOICES).values(),
dict(Asset.STATUS_CHOICES).keys())) dict(Asset.STATUS_CHOICES).keys()))
asset_status = asset_display_status_map.get(asset_dict['status'], 'In use') asset_status = asset_display_status_map.get(asset_dict['status'], 'In use')
asset_dict['status'] = asset_status asset_dict['status'] = asset_status
if asset_dict.get('env'): if asset_dict.get('env'):
asset_display_env_map = dict(zip(dict(Asset.ENV_CHOICES).values(), asset_display_env_map = dict(zip(dict(Asset.ENV_CHOICES).values(),
dict(Asset.ENV_CHOICES).keys())) dict(Asset.ENV_CHOICES).keys()))
asset_env = asset_display_env_map.get(asset_dict['env'], 'Prod') asset_env = asset_display_env_map.get(asset_dict['env'], 'Prod')
asset_dict['env'] = asset_env asset_dict['env'] = asset_env
try: try:
Asset.objects.create(**asset_dict) Asset.objects.create(**asset_dict)
created.append(asset_dict['ip']) created.append(asset_dict['ip'])
except IntegrityError as e: except IntegrityError as e:
asset = Asset.objects.filter(ip=asset_dict['ip'], port=asset_dict['port']) asset = Asset.objects.filter(ip=asset_dict['ip'], port=asset_dict['port'])
if not asset: if not asset:
failed.append(asset_dict['ip']) failed.append(asset_dict['ip'])
continue continue
asset.update(**asset_dict) asset.update(**asset_dict)
updated.append(asset_dict['ip']) updated.append(asset_dict['ip'])
except TypeError as e: except TypeError as e:
print(e) print(e)
failed.append(asset_dict['ip']) failed.append(asset_dict['ip'])
data = { data = {
'created': created, 'created': created,
'created_info': 'Created {}'.format(len(created)), 'created_info': 'Created {}'.format(len(created)),
'updated': updated, 'updated': updated,
'updated_info': 'Updated {}'.format(len(updated)), 'updated_info': 'Updated {}'.format(len(updated)),
'failed': failed, 'failed': failed,
'failed_info': 'Failed {}'.format(len(failed)), 'failed_info': 'Failed {}'.format(len(failed)),
'valid': True, 'valid': True,
'msg': 'Created: {}. Updated: {}, Error: {}'.format(len(created), len(updated), len(failed)) 'msg': 'Created: {}. Updated: {}, Error: {}'.format(len(created), len(updated), len(failed))
} }
return self.render_json_response(data) return self.render_json_response(data)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment