From dbdb8a58fed770d7146fd8c9ab702c9709b4caa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=B3=E4=B9=A6=E5=83=AE?= <343306138@qq.com> Date: Fri, 6 Jan 2017 20:34:24 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=84=E4=BA=A7=E7=9B=B8=E5=85=B3API?= =?UTF-8?q?=E5=8F=8AWeb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api.py | 183 ++- apps/assets/forms.py | 502 +++---- apps/assets/models.py | 28 +- apps/assets/serializers.py | 206 ++- .../assets/_asset_bulk_update_modal.html | 80 +- .../_asset_group_bulk_update_modal.html | 42 + .../templates/assets/admin_user_detail.html | 234 ++- .../templates/assets/admin_user_list.html | 76 + .../assets/templates/assets/asset_detail.html | 9 +- .../templates/assets/asset_group_detail.html | 326 ++++- .../templates/assets/asset_group_list.html | 138 +- apps/assets/templates/assets/asset_list.html | 319 +++-- .../templates/assets/asset_tag_detail.html | 244 ++-- .../templates/assets/asset_tags_list.html | 174 ++- apps/assets/templates/assets/idc_assets.html | 298 +++- apps/assets/templates/assets/idc_detail.html | 69 +- apps/assets/templates/assets/idc_list.html | 88 +- .../templates/assets/system_user_asset.html | 284 +++- .../templates/assets/system_user_list.html | 121 +- apps/assets/urls/api_urls.py | 27 +- apps/assets/views.py | 1272 +++++++++-------- 21 files changed, 3190 insertions(+), 1530 deletions(-) create mode 100644 apps/assets/templates/assets/_asset_group_bulk_update_modal.html diff --git a/apps/assets/api.py b/apps/assets/api.py index e96f1cdab..38451f8cb 100644 --- a/apps/assets/api.py +++ b/apps/assets/api.py @@ -3,66 +3,106 @@ from rest_framework import viewsets, generics, mixins from rest_framework.response import Response 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 django.shortcuts import get_object_or_404 from common.mixins import IDInFilterMixin from common.utils import get_object_or_none, signer 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 -class AssetViewSet(IDInFilterMixin, viewsets.ModelViewSet): - """API endpoint that allows Asset to be viewed or edited.""" - queryset = Asset.objects.all() - serializer_class = serializers.AssetSerializer - filter_fields = ('id', 'ip', 'hostname') +class AssetViewSet(IDInFilterMixin, BulkModelViewSet): + """API endpoint that allows Asset to be viewed or edited.""" + queryset = Asset.objects.all() + serializer_class = serializers.AssetSerializer + 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', '') - asset_group_id = self.request.query_params.get('asset_group_id', '') - if idc_id: - queryset = queryset.filter(idc__id=idc_id) - - if asset_group_id: - queryset = queryset.filter(groups__id=asset_group_id) - return queryset + 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(viewsets.ModelViewSet): - """ API endpoint that allows AssetGroup to be viewed or edited. - some other comment - """ - queryset = AssetGroup.objects.all() - serializer_class = serializers.AssetGroupSerializer +class AssetGroupViewSet(IDInFilterMixin, BulkModelViewSet): + queryset = AssetGroup.objects.all() + serializer_class = serializers.AssetGroupSerializer + permission_classes = (IsSuperUser,) class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView): - queryset = Asset.objects.all() - serializer_class = serializers.AssetUpdateGroupSerializer - permission_classes = (IsSuperUser,) + queryset = Asset.objects.all() + serializer_class = serializers.AssetUpdateGroupSerializer + 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,) +## update the asset group, and add or delete the asset to the group +class AssetGroupUpdateApi(generics.RetrieveUpdateAPIView): + queryset = AssetGroup.objects.all() + serializer_class = serializers.AssetGroupUpdateSerializer + permission_classes = (IsSuperUser,) -class AdminUserViewSet(viewsets.ModelViewSet): - queryset = AdminUser.objects.all() - serializer_class = serializers.AdminUserSerializer - 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 SystemUserViewSet(viewsets.ModelViewSet): - queryset = SystemUser.objects.all() - serializer_class = serializers.SystemUserSerializer - permission_classes = (IsSuperUser,) class SystemUserUpdateApi(generics.RetrieveUpdateAPIView): - queryset = Asset.objects.all() - serializer_class = serializers.AssetUpdateSystemUserSerializer - permission_classes = (IsSuperUser,) + queryset = Asset.objects.all() + serializer_class = serializers.AssetUpdateSystemUserSerializer + permission_classes = (IsSuperUser,) + +class SystemUserUpdateAssetsApi(generics.RetrieveUpdateAPIView): + queryset = SystemUser.objects.all() + serializer_class = serializers.SystemUserUpdateAssetsSerializer + permission_classes = (IsSuperUser,) + +class SystemUserUpdateAssetGroupApi(generics.RetrieveUpdateAPIView): + queryset = SystemUser.objects.all() + serializer_class = serializers.SystemUserUpdateAssetGroupSerializer + permission_classes = (IsSuperUser,) # class IDCAssetsApi(generics.ListAPIView): @@ -79,39 +119,50 @@ class SystemUserUpdateApi(generics.RetrieveUpdateAPIView): class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView): - queryset = Asset.objects.all() - serializer_class = serializers.AssetSerializer - permission_classes = (IsSuperUser,) + queryset = Asset.objects.all() + serializer_class = serializers.AssetSerializer + permission_classes = (IsSuperUser,) class SystemUserAuthApi(APIView): - permission_classes = (IsSuperUserOrTerminalUser,) + permission_classes = (IsSuperUserOrTerminalUser,) - def get(self, request, *args, **kwargs): - system_user_id = request.query_params.get('system_user_id', -1) - system_user_username = request.query_params.get('system_user_username', '') + def get(self, request, *args, **kwargs): + system_user_id = request.query_params.get('system_user_id', -1) + 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.password: - password = signer.sign(system_user.password) - else: - password = signer.sign('') + if system_user: + if system_user.password: + password = signer.sign(system_user.password) + else: + password = signer.sign('') - if system_user.private_key: - private_key = signer.sign(system_user.private_key) - else: - private_key = signer.sign(None) + if system_user.private_key: + private_key = signer.sign(system_user.private_key) + else: + private_key = signer.sign(None) - response = { - 'id': system_user.id, - 'password': password, - 'private_key': private_key, - } + response = { + 'id': system_user.id, + 'password': password, + 'private_key': private_key, + } - return Response(response) - else: - return Response({'msg': 'error system user id or username'}, status=401) + return Response(response) + else: + 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,) + diff --git a/apps/assets/forms.py b/apps/assets/forms.py index aeb7062cb..677b9c4e5 100644 --- a/apps/assets/forms.py +++ b/apps/assets/forms.py @@ -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')}), # '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')}), - # } + # } # class AssetCreateForm(forms.ModelForm): - def __init__(self, *args, **kwargs): - instance = kwargs.get('instance', None) - if instance: - initial = kwargs.get('initial', {}) - initial['tags'] = [t.pk for t in kwargs['instance'].tags.all()] - super(AssetCreateForm, self).__init__(*args, **kwargs) + def __init__(self, *args, **kwargs): + instance = kwargs.get('instance', None) + if instance: + initial = kwargs.get('initial', {}) + initial['tags'] = [t.pk for t in kwargs['instance'].tags.all()] + super(AssetCreateForm, self).__init__(*args, **kwargs) - def _save_m2m(self): - super(AssetCreateForm, self)._save_m2m() - tags = self.cleaned_data['tags'] - self.instance.tags.clear() - self.instance.tags.add(*tuple(tags)) + def _save_m2m(self): + super(AssetCreateForm, self)._save_m2m() + tags = self.cleaned_data['tags'] + self.instance.tags.clear() + self.instance.tags.add(*tuple(tags)) - class Meta: - model = Asset - tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all()) - fields = [ - 'hostname', 'ip', 'port', 'type', 'comment', 'admin_user', 'system_users', 'idc', 'groups', - 'other_ip', 'remote_card_ip', 'mac_address', 'brand', 'cpu', 'memory', 'disk', 'os', 'cabinet_no', - 'cabinet_pos', 'number', 'status', 'env', 'sn', 'tags', - ] - widgets = { - 'groups': forms.SelectMultiple(attrs={'class': 'select2', - 'data-placeholder': _('Select asset groups')}), - 'tags': forms.SelectMultiple(attrs={'class': 'select2', - 'data-placeholder': _('Select asset tags')}), - 'system_users': forms.SelectMultiple(attrs={'class': 'select2', - '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个汉字,按回车确认' - } + def clean(self): + clean_data = super(AssetCreateForm, self).clean() + ip = clean_data.get('ip') + port = clean_data.get('port') + query = Asset.objects.filter(ip=ip, port=port) + if query: + raise forms.ValidationError('this asset has exists.') + + class Meta: + model = Asset + tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all()) + fields = [ + 'hostname', 'ip', 'port', 'type', 'comment', 'admin_user', 'system_users', 'idc', 'groups', + 'other_ip', 'remote_card_ip', 'mac_address', 'brand', 'cpu', 'memory', 'disk', 'os', 'cabinet_no', + 'cabinet_pos', 'number', 'status', 'env', 'sn', 'tags', + ] + widgets = { + 'groups': forms.SelectMultiple(attrs={'class': 'select2', + 'data-placeholder': _('Select asset groups')}), + 'tags': forms.SelectMultiple(attrs={'class': 'select2', + 'data-placeholder': _('Select asset tags')}), + 'system_users': forms.SelectMultiple(attrs={'class': 'select2', + '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): - # See AdminUserForm comment same it - assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), - label=_('Asset'), - required=False, - widget=forms.SelectMultiple( - attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) - ) + # See AdminUserForm comment same it + assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), + label=_('Asset'), + required=False, + widget=forms.SelectMultiple( + attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) + ) - def __init__(self, *args, **kwargs): - if kwargs.get('instance', None): - initial = kwargs.get('initial', {}) - initial['assets'] = kwargs['instance'].assets.all() - super(AssetGroupForm, self).__init__(*args, **kwargs) + def __init__(self, *args, **kwargs): + if kwargs.get('instance', None): + initial = kwargs.get('initial', {}) + initial['assets'] = kwargs['instance'].assets.all() + super(AssetGroupForm, self).__init__(*args, **kwargs) - def _save_m2m(self): - super(AssetGroupForm, self)._save_m2m() - assets = self.cleaned_data['assets'] - self.instance.assets.clear() - self.instance.assets.add(*tuple(assets)) + def _save_m2m(self): + super(AssetGroupForm, self)._save_m2m() + assets = self.cleaned_data['assets'] + self.instance.assets.clear() + self.instance.assets.add(*tuple(assets)) - class Meta: - model = AssetGroup - fields = [ - "name", "comment","system_users", - ] - widgets = { - 'name' : forms.TextInput(attrs={}), - 'system_users': forms.SelectMultiple(attrs={'class': 'select2-system-user', 'data-placeholder': _('Select asset system user')}), + class Meta: + model = AssetGroup + fields = [ + "name", "comment","system_users", + ] + widgets = { + 'name' : forms.TextInput(attrs={}), + 'system_users': forms.SelectMultiple(attrs={'class': 'select2-system-user', 'data-placeholder': _('Select asset system user')}), - } - help_texts = { - 'name': '* required', - } + } + help_texts = { + 'name': '* required', + } class IDCForm(forms.ModelForm): - # See AdminUserForm comment same it - assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), - label=_('Asset'), - required=False, - widget=forms.SelectMultiple( - attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) - ) + # See AdminUserForm comment same it + assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), + label=_('Asset'), + required=False, + widget=forms.SelectMultiple( + attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) + ) - def __init__(self, *args, **kwargs): - if kwargs.get('instance'): - initial = kwargs.get('initial', {}) - initial['assets'] = kwargs['instance'].assets.all() - super(IDCForm, self).__init__(*args, **kwargs) + def __init__(self, *args, **kwargs): + if kwargs.get('instance'): + initial = kwargs.get('initial', {}) + initial['assets'] = kwargs['instance'].assets.all() + super(IDCForm, self).__init__(*args, **kwargs) - def _save_m2m(self): - super(IDCForm, self)._save_m2m() - assets = self.cleaned_data['assets'] - self.instance.assets.clear() - self.instance.assets.add(*tuple(assets)) + def _save_m2m(self): + super(IDCForm, self)._save_m2m() + assets = self.cleaned_data['assets'] + self.instance.assets.clear() + self.instance.assets.add(*tuple(assets)) - class Meta: - model = IDC - fields = ['name', "bandwidth", "operator", 'contact', 'phone', 'address', 'intranet', 'extranet','comment'] - widgets = { - 'name': forms.TextInput(attrs={'placeholder': _('Name')}), - 'intranet': forms.Textarea( - attrs={'placeholder': 'IP段之间用逗号隔开,如:192.168.1.0/24,192.168.1.0/24'}), - 'extranet': forms.Textarea( - attrs={'placeholder': 'IP段之间用逗号隔开,如:201.1.32.1/24,202.2.32.1/24'}) - } + class Meta: + model = IDC + fields = ['name', "bandwidth", "operator", 'contact', 'phone', 'address', 'intranet', 'extranet','comment'] + widgets = { + 'name': forms.TextInput(attrs={'placeholder': _('Name')}), + 'intranet': forms.Textarea( + attrs={'placeholder': 'IP段之间用逗号隔开,如:192.168.1.0/24,192.168.1.0/24'}), + 'extranet': forms.Textarea( + attrs={'placeholder': 'IP段之间用逗号隔开,如:201.1.32.1/24,202.2.32.1/24'}) + } class AdminUserForm(forms.ModelForm): - # Admin user assets define, let user select, save it in form not in view - assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), - label=_('Asset'), - required=False, - widget=forms.SelectMultiple( - attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) - ) - # Form field name can not start with `_`, so redefine it, - 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) - # Need use upload private key file except paste private key content - private_key_file = forms.FileField(required=False) + # Admin user assets define, let user select, save it in form not in view + assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), + label=_('Asset'), + required=False, + widget=forms.SelectMultiple( + attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) + ) + # Form field name can not start with `_`, so redefine it, + 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) + # Need use upload private key file except paste private key content + private_key_file = forms.FileField(required=False) - def __init__(self, *args, **kwargs): - # When update a admin user instance, initial it - if kwargs.get('instance'): - initial = kwargs.get('initial', {}) - initial['assets'] = kwargs['instance'].assets.all() - super(AdminUserForm, self).__init__(*args, **kwargs) + def __init__(self, *args, **kwargs): + # When update a admin user instance, initial it + if kwargs.get('instance'): + initial = kwargs.get('initial', {}) + initial['assets'] = kwargs['instance'].assets.all() + super(AdminUserForm, self).__init__(*args, **kwargs) - def _save_m2m(self): - # Save assets relation with admin user - super(AdminUserForm, self)._save_m2m() - assets = self.cleaned_data['assets'] - self.instance.assets.clear() - self.instance.assets.add(*tuple(assets)) + def _save_m2m(self): + # Save assets relation with admin user + super(AdminUserForm, self)._save_m2m() + assets = self.cleaned_data['assets'] + self.instance.assets.clear() + self.instance.assets.add(*tuple(assets)) - def save(self, commit=True): - # Because we define custom field, so we need rewrite :method: `save` - admin_user = super(AdminUserForm, self).save(commit=commit) - password = self.cleaned_data['password'] - private_key = self.cleaned_data['private_key_file'] - public_key = ssh_pubkey_gen(private_key) + def save(self, commit=True): + # Because we define custom field, so we need rewrite :method: `save` + admin_user = super(AdminUserForm, self).save(commit=commit) + password = self.cleaned_data['password'] + private_key = self.cleaned_data['private_key_file'] + public_key = ssh_pubkey_gen(private_key) - if password: - admin_user.password = password - if private_key: - admin_user.private_key = private_key - admin_user.public_key = public_key - admin_user.save() - return admin_user + if password: + admin_user.password = password + if private_key: + admin_user.private_key = private_key + admin_user.public_key = public_key + admin_user.save() + return admin_user - def clean_private_key_file(self): - private_key_file = self.cleaned_data['private_key_file'] - if private_key_file: - private_key = private_key_file.read() - if not validate_ssh_private_key(private_key): - raise forms.ValidationError(_('Invalid private key')) - return private_key - return private_key_file + def clean_private_key_file(self): + private_key_file = self.cleaned_data['private_key_file'] + if private_key_file: + private_key = private_key_file.read() + if not validate_ssh_private_key(private_key): + raise forms.ValidationError(_('Invalid private key')) + return private_key + return private_key_file - def clean(self): - password = self.cleaned_data['password'] - private_key_file = self.cleaned_data.get('private_key_file', '') + def clean(self): + password = self.cleaned_data['password'] + private_key_file = self.cleaned_data.get('private_key_file', '') - if not (password or private_key_file): - raise forms.ValidationError(_('Password and private key file must be input one')) + if not (password or private_key_file): + raise forms.ValidationError(_('Password and private key file must be input one')) - class Meta: - model = AdminUser - fields = ['name', 'username', 'password', 'private_key_file', 'comment'] - widgets = { - 'name': forms.TextInput(attrs={'placeholder': _('Name')}), - 'username': forms.TextInput(attrs={'placeholder': _('Username')}), - } - help_texts = { - 'name': '* required', - 'username': '* required', - } + class Meta: + model = AdminUser + fields = ['name', 'username', 'password', 'private_key_file', 'comment'] + widgets = { + 'name': forms.TextInput(attrs={'placeholder': _('Name')}), + 'username': forms.TextInput(attrs={'placeholder': _('Username')}), + } + help_texts = { + 'name': '* required', + 'username': '* required', + } class SystemUserForm(forms.ModelForm): - # Admin user assets define, let user select, save it in form not in view - assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), - label=_('Asset'), - required=False, - widget=forms.SelectMultiple( - attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) - ) - asset_groups = forms.ModelMultipleChoiceField(queryset=AssetGroup.objects.all(), - label=_('Asset group'), - required=False, - widget=forms.SelectMultiple( - attrs={'class': 'select2', - 'data-placeholder': _('Select asset groups')}) - ) - auto_generate_key = forms.BooleanField(initial=True) - # Form field name can not start with `_`, so redefine it, - 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) - # Need use upload private key file except paste private key content - private_key_file = forms.FileField(required=False) + # Admin user assets define, let user select, save it in form not in view + assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), + label=_('Asset'), + required=False, + widget=forms.SelectMultiple( + attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) + ) + asset_groups = forms.ModelMultipleChoiceField(queryset=AssetGroup.objects.all(), + label=_('Asset group'), + required=False, + widget=forms.SelectMultiple( + attrs={'class': 'select2', + 'data-placeholder': _('Select asset groups')}) + ) + auto_generate_key = forms.BooleanField(initial=True) + # Form field name can not start with `_`, so redefine it, + 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) + # Need use upload private key file except paste private key content + private_key_file = forms.FileField(required=False) - def __init__(self, *args, **kwargs): - # When update a admin user instance, initial it - if kwargs.get('instance'): - initial = kwargs.get('initial', {}) - initial['assets'] = kwargs['instance'].assets.all() - initial['asset_groups'] = kwargs['instance'].asset_groups.all() - super(SystemUserForm, self).__init__(*args, **kwargs) + def __init__(self, *args, **kwargs): + # When update a admin user instance, initial it + if kwargs.get('instance'): + initial = kwargs.get('initial', {}) + initial['assets'] = kwargs['instance'].assets.all() + initial['asset_groups'] = kwargs['instance'].asset_groups.all() + super(SystemUserForm, self).__init__(*args, **kwargs) - def _save_m2m(self): - # Save assets relation with admin user - super(SystemUserForm, self)._save_m2m() - assets = self.cleaned_data['assets'] - asset_groups = self.cleaned_data['asset_groups'] - self.instance.assets.clear() - self.instance.assets.add(*tuple(assets)) - self.instance.asset_groups.clear() - self.instance.asset_groups.add(*tuple(asset_groups)) + def _save_m2m(self): + # Save assets relation with admin user + super(SystemUserForm, self)._save_m2m() + assets = self.cleaned_data['assets'] + asset_groups = self.cleaned_data['asset_groups'] + self.instance.assets.clear() + self.instance.assets.add(*tuple(assets)) + self.instance.asset_groups.clear() + self.instance.asset_groups.add(*tuple(asset_groups)) - def save(self, commit=True): - # Because we define custom field, so we need rewrite :method: `save` - system_user = super(SystemUserForm, self).save(commit=commit) - password = self.cleaned_data['password'] - private_key_file = self.cleaned_data['private_key_file'] + def save(self, commit=True): + # Because we define custom field, so we need rewrite :method: `save` + system_user = super(SystemUserForm, self).save(commit=commit) + password = self.cleaned_data['password'] + private_key_file = self.cleaned_data['private_key_file'] - if password: - system_user.password = password - print(password) - # Todo: Validate private key file, and generate public key - # Todo: Auto generate private key and public key - if private_key_file: - system_user.private_key = private_key_file.read().strip() - system_user.save() - return self.instance + if password: + system_user.password = password + print(password) + # Todo: Validate private key file, and generate public key + # Todo: Auto generate private key and public key + if private_key_file: + system_user.private_key = private_key_file.read().strip() + system_user.save() + return self.instance - class Meta: - model = SystemUser - fields = [ - 'name', 'username', 'protocol', 'auto_generate_key', 'password', 'private_key_file', 'as_default', - 'auto_push', 'auto_update', 'sudo', 'comment', 'shell', 'home', 'uid', - ] - widgets = { - 'name': forms.TextInput(attrs={'placeholder': _('Name')}), - 'username': forms.TextInput(attrs={'placeholder': _('Username')}), - } - help_texts = { - 'name': '* required', - 'username': '* required', - 'auth_push': 'Auto push system user to asset', - 'auth_update': 'Auto update system user ssh key', - } + class Meta: + model = SystemUser + fields = [ + 'name', 'username', 'protocol', 'auto_generate_key', 'password', 'private_key_file', 'as_default', + 'auto_push', 'auto_update', 'sudo', 'comment', 'shell', 'home', 'uid', + ] + widgets = { + 'name': forms.TextInput(attrs={'placeholder': _('Name')}), + 'username': forms.TextInput(attrs={'placeholder': _('Username')}), + } + help_texts = { + 'name': '* required', + 'username': '* required', + 'auth_push': 'Auto push system user to asset', + 'auth_update': 'Auto update system user ssh key', + } class AssetTagForm(forms.ModelForm): - assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), - label=_('Asset'), - required=False, - widget=forms.SelectMultiple( - attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) - ) + assets = forms.ModelMultipleChoiceField(queryset=Asset.objects.all(), + label=_('Asset'), + required=False, + widget=forms.SelectMultiple( + attrs={'class': 'select2', 'data-placeholder': _('Select assets')}) + ) - def __init__(self, *args, **kwargs): - if kwargs.get('instance', None): - initial = kwargs.get('initial', {}) - initial['assets'] = kwargs['instance'].asset_set.all() - super(AssetTagForm, self).__init__(*args, **kwargs) + def __init__(self, *args, **kwargs): + if kwargs.get('instance', None): + initial = kwargs.get('initial', {}) + initial['assets'] = kwargs['instance'].asset_set.all() + super(AssetTagForm, self).__init__(*args, **kwargs) - def _save_m2m(self): - super(AssetTagForm, self)._save_m2m() - assets = self.cleaned_data['assets'] - self.instance.asset_set.clear() - self.instance.asset_set.add(*tuple(assets)) + def _save_m2m(self): + assets = self.cleaned_data['assets'] + self.instance.assets.clear() + self.instance.assets.add(*tuple(assets)) + super(AssetTagForm, self)._save_m2m() - class Meta: - model = Tag - fields = [ - "name", - ] - widgets = { - 'name' : forms.TextInput(attrs={}), + class Meta: + model = Tag + fields = [ + "name", + ] + widgets = { + 'name' : forms.TextInput(attrs={}), - } - help_texts = { - 'name': '* required', - } + } + help_texts = { + 'name': '* required', + } class FileForm(forms.Form): - file = forms.FileField() \ No newline at end of file + file = forms.FileField() \ No newline at end of file diff --git a/apps/assets/models.py b/apps/assets/models.py index aa22a2f02..7cd025946 100644 --- a/apps/assets/models.py +++ b/apps/assets/models.py @@ -269,6 +269,19 @@ class AssetGroup(models.Model): def get_default_idc(): 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): STATUS_CHOICES = ( @@ -320,7 +333,7 @@ class Asset(models.Model): 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')) 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): return '%(ip)s:%(port)s' % {'ip': self.ip, 'port': self.port} @@ -339,7 +352,7 @@ class Asset(models.Model): class Meta: db_table = 'asset' - unique_together = ('ip', 'port') + # unique_together = ('ip', 'port') @classmethod def generate_fake(cls, count=100): @@ -365,18 +378,7 @@ class Asset(models.Model): 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(): diff --git a/apps/assets/serializers.py b/apps/assets/serializers.py index 6e6353a86..d99f3eb56 100644 --- a/apps/assets/serializers.py +++ b/apps/assets/serializers.py @@ -1,112 +1,172 @@ # -*- coding: utf-8 -*- from django.utils.translation import ugettext_lazy as _ 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 rest_framework_bulk import BulkListSerializer, BulkSerializerMixin -class AssetGroupSerializer(serializers.ModelSerializer): - assets_amount = serializers.SerializerMethodField() - # assets = serializers.PrimaryKeyRelatedField(many=True, read_only=True) +class AssetGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer): + assets_amount = serializers.SerializerMethodField() + assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all()) - class Meta: - model = AssetGroup + class Meta: + model = AssetGroup + list_serializer_class = BulkListSerializer - @staticmethod - def get_assets_amount(obj): - return obj.assets.count() + @staticmethod + def get_assets_amount(obj): + return obj.assets.count() class AssetUpdateGroupSerializer(serializers.ModelSerializer): - groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all()) + groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all()) - class Meta: - model = Asset - fields = ['id', 'groups'] + class Meta: + model = Asset + fields = ['id', 'groups'] 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 Meta: - model = AdminUser + assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all()) + class Meta: + model = AdminUser - def get_field_names(self, declared_fields, info): - fields = super(AdminUserSerializer, self).get_field_names(declared_fields, info) - fields.append('assets_amount') - return fields + def get_field_names(self, declared_fields, info): + fields = super(AdminUserSerializer, self).get_field_names(declared_fields, info) + fields.append('assets_amount') + return fields class SystemUserSerializer(serializers.ModelSerializer): - class Meta: - model = SystemUser - exclude = ('_password', '_private_key', '_public_key') + class Meta: + model = SystemUser + exclude = ('_password', '_private_key', '_public_key') - def get_field_names(self, declared_fields, info): - fields = super(SystemUserSerializer, self).get_field_names(declared_fields, info) - fields.extend(['assets_amount']) - return fields + def get_field_names(self, declared_fields, info): + fields = super(SystemUserSerializer, self).get_field_names(declared_fields, info) + fields.extend(['assets_amount']) + 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): - # system_users = SystemUserSerializer(many=True, read_only=True) - # admin_user = AdminUserSerializer(many=False, read_only=True) - hardware = serializers.SerializerMethodField() + # system_users = SystemUserSerializer(many=True, read_only=True) + # admin_user = AdminUserSerializer(many=False, read_only=True) + hardware = serializers.SerializerMethodField() - class Meta(object): - model = Asset - list_serializer_class = BulkListSerializer + class Meta(object): + model = Asset + list_serializer_class = BulkListSerializer - @staticmethod - def get_hardware(obj): - if obj.cpu: - return '%s %s %s' % (obj.cpu, obj.memory, obj.disk) - else: - return '' + @staticmethod + def get_hardware(obj): + if obj.cpu: + return '%s %s %s' % (obj.cpu, obj.memory, obj.disk) + else: + return '' - def get_field_names(self, declared_fields, info): - fields = super(AssetSerializer, self).get_field_names(declared_fields, info) - fields.extend(['get_type_display', 'get_env_display']) - return fields + def get_field_names(self, declared_fields, info): + fields = super(AssetSerializer, self).get_field_names(declared_fields, info) + fields.extend(['get_type_display', 'get_env_display']) + return fields class AssetGrantedSerializer(serializers.ModelSerializer): - system_users = SystemUserSerializer(many=True, read_only=True) - is_inherited = serializers.SerializerMethodField() - system_users_join = serializers.SerializerMethodField() + system_users = SystemUserSerializer(many=True, read_only=True) + is_inherited = 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") + 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_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()]) + @staticmethod + def get_system_users_join(obj): + return ', '.join([system_user.username for system_user in obj.system_users.all()]) -class IDCSerializer(serializers.ModelSerializer): - assets_amount = serializers.SerializerMethodField() +class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer): + assets_amount = serializers.SerializerMethodField() + assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all()) - class Meta: - model = IDC + class Meta: + model = IDC - @staticmethod - def get_assets_amount(obj): - return obj.assets.count() + @staticmethod + def get_assets_amount(obj): + return obj.assets.count() - def get_field_names(self, declared_fields, info): - fields = super(IDCSerializer, self).get_field_names(declared_fields, info) - fields.append('assets_amount') - return fields + def get_field_names(self, declared_fields, info): + fields = super(IDCSerializer, self).get_field_names(declared_fields, info) + fields.append('assets_amount') + return fields + + +class TagUpdateAssetsSerializer(serializers.ModelSerializer): + assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all()) + + class Meta: + model = Tag + fields = ['id', 'assets'] \ No newline at end of file diff --git a/apps/assets/templates/assets/_asset_bulk_update_modal.html b/apps/assets/templates/assets/_asset_bulk_update_modal.html index 35b74492f..391fc5361 100644 --- a/apps/assets/templates/assets/_asset_bulk_update_modal.html +++ b/apps/assets/templates/assets/_asset_bulk_update_modal.html @@ -6,30 +6,33 @@ {% block modal_body %} {% load bootstrap %}

{% trans "Hint: only change the field you want to update." %}

- -
-
-

- - 三年质保(0) - -

-
-
+
+
+

+ + 三年质保(0) + +

+
+
- +
- - - + + + + + +
-
- +
+
+ +
+ +
+ +
+
+
@@ -48,28 +63,17 @@
- - - - - -
- - - - - -

- 最多5个标签,单个标签最长8个汉字,按回车确认 -

- -
+ +
+ +

+ 最多5个标签,单个标签最长8个汉字,按回车确认 +

+
diff --git a/apps/assets/templates/assets/_asset_group_bulk_update_modal.html b/apps/assets/templates/assets/_asset_group_bulk_update_modal.html new file mode 100644 index 000000000..80967da34 --- /dev/null +++ b/apps/assets/templates/assets/_asset_group_bulk_update_modal.html @@ -0,0 +1,42 @@ +{% extends '_modal.html' %} +{% load i18n %} +{% block modal_id %}asset_group_bulk_update_modal{% endblock %} +{% block modal_class %}modal-lg{% endblock %} +{% block modal_title%}{% trans "Update Asset Group" %}{% endblock %} +{% block modal_body %} +{% load bootstrap %} +

{% trans "Hint: only change the field you want to update." %}

+ + +
+ +
+ +
+
+
+ +
+ +
+
+ +
+
+
+ +
+
+
+ + +{% endblock %} +{% block modal_confirm_id %}btn_asset_group_bulk_update{% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/admin_user_detail.html b/apps/assets/templates/assets/admin_user_detail.html index 85dba09ef..53948921b 100644 --- a/apps/assets/templates/assets/admin_user_detail.html +++ b/apps/assets/templates/assets/admin_user_detail.html @@ -88,29 +88,30 @@
- +
+ - {% for asset in page_obj %} - - - - - - - {% endfor %} +{# {% for asset in page_obj %}#} +{# #} +{# #} +{# #} +{# #} +{# #} +{# #} +{# {% endfor %}#}
{% trans 'Hostname' %} {% trans 'IP' %} {% trans 'Port' %} {% trans 'Alive' %}{% trans 'Action' %}
{{ asset.hostname }}{{ asset.ip }}{{ asset.port }}Alive
{{ asset.hostname }}{{ asset.ip }}{{ asset.port }}Alive
-
- {% include '_pagination.html' %} -
+{#
#} +{# {% include '_pagination.html' %}#} +{#
#}
@@ -164,15 +165,15 @@ - + @@ -192,15 +193,15 @@ - + @@ -218,26 +219,181 @@ {% endblock %} {% block custom_foot_js %} - + } + 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 = '' + cellData + ''; + $(td).html(detail_btn.replace('99991937', rowData.id)); + }}, + {targets: 3, createdCell: function (td, cellData) { + if (!cellData) { + $(td).html('') + } else { + $(td).html('') + } + }}, + {targets: 4, createdCell: function (td, cellData, rowData) { + var update_btn = '{% trans "Update" %}'.replace('99991937', rowData.id); + var del_btn = '{% trans "Remove" %}'.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 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 {% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/admin_user_list.html b/apps/assets/templates/assets/admin_user_list.html index 35d6b6789..44cd1bf06 100644 --- a/apps/assets/templates/assets/admin_user_list.html +++ b/apps/assets/templates/assets/admin_user_list.html @@ -23,6 +23,18 @@ +
+
+ +
+ +
+
+
{% endblock %} {% block content_bottom_left %}{% endblock %} {% block custom_foot_js %} @@ -48,8 +60,72 @@ $(document).ready(function(){ ajax_url: '{% url "api-assets:admin-user-list" %}', columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () {return 'lost'} }, {data: "comment" }, {data: "id" }], + op_html: $('#actions').html() }; 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; + } }); {% endblock %} diff --git a/apps/assets/templates/assets/asset_detail.html b/apps/assets/templates/assets/asset_detail.html index ca1b667ed..18f05e39c 100644 --- a/apps/assets/templates/assets/asset_detail.html +++ b/apps/assets/templates/assets/asset_detail.html @@ -200,7 +200,7 @@ {% trans 'Asset groups' %}
- +
@@ -236,7 +236,7 @@ {% trans 'System users' %}
-
+
@@ -288,7 +288,7 @@ function updateAssetGroups(groups) { $.map(jumpserver.groups_selected, function(group_name, index) { $('#opt_' + index).remove(); // change tr html of user groups. - $('.group_edit tbody').append( + $('#add-asset2group tbody').append( '' + '' + '' + @@ -316,7 +316,7 @@ function updateAssetSystem(system_users) { $.map(jumpserver.groups_selected, function(name, index) { $('#opt_' + index).remove(); - $('.group_edit tbody').append( + $('#add-asset2systemuser tbody').append( '' + '' + '' + @@ -418,7 +418,6 @@ $(document).ready(function () { var system_users = $('.bdg_group').map(function () { return $(this).data('sid'); }).get(); - console.log(system_users); updateAssetSystem(system_users) }) diff --git a/apps/assets/templates/assets/asset_group_detail.html b/apps/assets/templates/assets/asset_group_detail.html index 2785918ff..94e41ad10 100644 --- a/apps/assets/templates/assets/asset_group_detail.html +++ b/apps/assets/templates/assets/asset_group_detail.html @@ -48,10 +48,28 @@ + + +{# {% for asset in assets %}#} +{# #} +{# #} +{# #} +{# #} +{# {% if asset.is_active %}#} +{# #} +{# {% else %}#} +{# #} +{# {% endif %}#} +{# #} +{# #} +{# {% endfor %}#}
' + group_name + '
' + name + '{% trans 'Hostname' %} {% trans 'IP' %} {% trans 'Port' %}{% trans 'Type' %} {% trans 'Alive' %}{% trans 'Action' %}
{{ asset.hostname }}{{ asset.ip }}{{ asset.port }}#} +{# {% trans "Delete" %}#} +{# {% trans "Update" %}#} +{#
@@ -70,14 +88,14 @@ - + @@ -91,29 +109,29 @@ {% trans 'Associate system user' %}
- +
{% for system_user in system_users %} - + {% endfor %} @@ -132,53 +150,249 @@ {% endblock %} {% block custom_foot_js %} - + {% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/asset_group_list.html b/apps/assets/templates/assets/asset_group_list.html index 6e46fc70c..1c11ea383 100644 --- a/apps/assets/templates/assets/asset_group_list.html +++ b/apps/assets/templates/assets/asset_group_list.html @@ -21,6 +21,20 @@
- +
{{ group.name }}{{ system_user.name }} - +
+
+
+ +
+ +
+
+
+{% include 'assets/_asset_group_bulk_update_modal.html' %} {% endblock %} {% block content_bottom_left %}{% endblock %} {% block custom_foot_js %} @@ -43,17 +57,125 @@ $(document).ready(function(){ $(td).html(update_btn + del_btn) }}], 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); }) - .on('click', '.btn_asset_group_delete', function () { - var $this = $(this); - var name = $(this).closest("tr").find(":nth-child(2)").children('a').html(); - var uid = $this.data('uid'); - var the_url = '{% url "api-assets:asset-group-detail" pk=99991937 %}'.replace('99991937', uid); - objectDelete($this, name, the_url); - }); + +.on('click', '.btn_asset_group_delete', function () { + var $this = $(this); + var $data_table = $('#asset_groups_list_table').DataTable(); + var name = $(this).closest("tr").find(":nth-child(2)").children('a').html(); + var uid = $this.data('uid'); + var the_url = '{% url "api-assets:asset-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'); +}); {% endblock %} diff --git a/apps/assets/templates/assets/asset_list.html b/apps/assets/templates/assets/asset_list.html index a5d43579c..1ee934363 100644 --- a/apps/assets/templates/assets/asset_list.html +++ b/apps/assets/templates/assets/asset_list.html @@ -72,6 +72,7 @@ +
{% include 'assets/_asset_import_modal.html' %} +{% include 'assets/_asset_bulk_update_modal.html' %} {% endblock %} {% block custom_foot_js %} {% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/asset_tag_detail.html b/apps/assets/templates/assets/asset_tag_detail.html index 983039cae..ac190af17 100644 --- a/apps/assets/templates/assets/asset_tag_detail.html +++ b/apps/assets/templates/assets/asset_tag_detail.html @@ -77,80 +77,27 @@
- +
- + + + - {% for asset in page_obj %} - - - - - - - {% endfor %}
{% trans 'Hostname' %} {% trans 'IP' %} {% trans 'Port' %}{% trans 'Alive' %}{% trans 'Type' %}{% trans 'Valid' %}{% trans 'Action' %}
{{ asset.hostname }}{{ asset.ip }}{{ asset.port }}Alive
-
- {% include '_pagination.html' %} -
- {% trans 'Associate system user' %} -
-
- - - - - - - - - - - - - - - {% for group in user.groups.all %} - - - - - {% endfor %} - -
{% trans 'repush system user' %}: - - - -
- -
- -
{{ group.name }} - -
-
-
- -
-
- {% trans 'Add asset to this group' %} + {% trans 'Add asset to this tag' %}
@@ -158,27 +105,19 @@ - {% for group in user.groups.all %} - - - - - {% endfor %}
- + {% for asset in assets_remain %} + {% endfor %}
- +
{{ group.name }} - -
@@ -194,26 +133,147 @@ {% endblock %} {% block custom_foot_js %} - + {% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/asset_tags_list.html b/apps/assets/templates/assets/asset_tags_list.html index cd8cdf559..7c3e20c7c 100644 --- a/apps/assets/templates/assets/asset_tags_list.html +++ b/apps/assets/templates/assets/asset_tags_list.html @@ -1,56 +1,126 @@ {% extends '_base_list.html' %} -{% load i18n %} -{% load common_tags %} -{% block content_left_head %} - {% trans "Create tag" %} +{% load i18n static %} +{#{% load common_tags %}#} +{% block custom_head_css_js %} + + {% endblock %} - -{% block table_head %} - - - - {% trans 'Tag Name' %} - {% trans 'Asset num' %} - -{% endblock %} - -{% block table_body %} - - {% for asset_tag in asset_tags_list %} - - - - - - - {{ asset_tag.name }} - - - {{ asset_tag.asset_set.count }} - - {% trans 'Update' %} - {% trans 'Delete' %} - - - {% endfor %} -{% endblock %} - -{% block content_bottom_left %} - +
@@ -59,13 +63,27 @@
+ +
+
+ +
+ +
+
+
+
- {% trans 'Attach to assets ' %} + {% trans 'Attach assets to IDC ' %}
@@ -75,14 +93,14 @@ @@ -96,33 +114,255 @@ - +{% include 'assets/_asset_bulk_update_modal.html' %} {% endblock %} {% block custom_foot_js %} - + + 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 = '' + cellData + ''; + $(td).html(detail_btn.replace('99991937', rowData.id)); + }}, + {targets: 5, createdCell: function (td, cellData) { + if (!cellData) { + $(td).html('') + } else { + $(td).html('') + } + }}], + 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'); +}); + + + + + + + {% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/idc_detail.html b/apps/assets/templates/assets/idc_detail.html index dc3143213..9073e6f1a 100644 --- a/apps/assets/templates/assets/idc_detail.html +++ b/apps/assets/templates/assets/idc_detail.html @@ -27,7 +27,7 @@ Update
  • - + Delete
  • @@ -53,9 +53,9 @@
    -
    - +
    +
    - + @@ -113,26 +113,47 @@ {% endblock %} {% block custom_foot_js %} - + } + 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); +}); + {% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/idc_list.html b/apps/assets/templates/assets/idc_list.html index f9ee96bb7..8663e5009 100644 --- a/apps/assets/templates/assets/idc_list.html +++ b/apps/assets/templates/assets/idc_list.html @@ -1,5 +1,9 @@ {% extends '_base_list.html' %} {% load i18n static %} +{% block custom_head_css_js %} + + +{% endblock %} {% block table_search %}{% endblock %} {% block table_container %}
    @@ -22,6 +26,18 @@
    {% trans 'Name' %}: {{ idc.name }}
    +
    +
    + +
    + +
    +
    +
    {% endblock %} {% block content_bottom_left %}{% endblock %} {% block custom_foot_js %} @@ -34,20 +50,10 @@ $(document).ready(function(){ var detail_btn = '' + cellData + ''; $(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('' + innerHtml + '');#} -{# }},#} -{# {targets: 6, createdCell: function (td, cellData) {#} -{# if (!cellData) {#} -{# $(td).html('')#} -{# } else {#} -{# $(td).html('')#} -{# }#} -{# }},#} + {targets: 6, createdCell: function (td, cellData, rowData) { var update_btn = '{% trans "Update" %}'.replace('99991937', cellData); - var del_btn = '{% trans "Delete" %}'.replace('99991937', cellData); + var del_btn = '{% trans "Delete" %}'.replace('99991937', cellData); $(td).html(update_btn + del_btn) }}], ajax_url: '{% url "api-assets:idc-list" %}', @@ -56,6 +62,64 @@ $(document).ready(function(){ op_html: $('#actions').html() }; 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; + } }); {% endblock %} diff --git a/apps/assets/templates/assets/system_user_asset.html b/apps/assets/templates/assets/system_user_asset.html index c3f22749b..522c58144 100644 --- a/apps/assets/templates/assets/system_user_asset.html +++ b/apps/assets/templates/assets/system_user_asset.html @@ -43,35 +43,35 @@
    - +
    - + - {% for asset in page_obj %} - - - - - - - - {% endfor %} +{# {% for asset in page_obj %}#} +{# #} +{# #} +{# #} +{# #} +{# #} +{# #} +{# #} +{# {% endfor %}#}
    {% trans 'Hostname' %} {% trans 'IP' %} {% trans 'Port' %} {% trans 'Reachable' %}{% trans 'Action' %}
    {{ asset.hostname }}{{ asset.ip }}{{ asset.port }} - - - -
    {{ asset.hostname }}{{ asset.ip }}{{ asset.port }}#} +{# #} +{# #} +{# #} +{#
    -
    - {% include '_pagination.html' %} -
    +{#
    #} +{# {% include '_pagination.html' %}#} +{#
    #}
    @@ -95,7 +95,7 @@ - + @@ -123,16 +123,16 @@ - + {% for asset_group in asset_groups %} - {{ asset_group.name }} + {{ asset_group.name }} - + {% endfor %} @@ -150,26 +150,224 @@ {% endblock %} {% block custom_foot_js %} - + } + 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( + '' + + '' + asset_groups + '' + + '' + + '' + ) + }); + 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 = '' + cellData + ''; + $(td).html(detail_btn.replace('99991937', rowData.id)); + }}, + {targets: 3, createdCell: function (td, cellData) { + if (!cellData) { + $(td).html('') + } else { + $(td).html('') + } + }}, + {targets: 4, createdCell: function (td, cellData, rowData) { + var update_btn = '{% trans "Update" %}'.replace('99991937', rowData.id); + var del_btn = '{% trans "Delete" %}'.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( + '' + ); + $tr.remove(); + var asset_groups = $('.bdg_asset_groups').map(function () { + return $(this).data('gid'); + }).get(); + updateSystemUserAssetGroup(asset_groups); +}); + + + + + {% endblock %} \ No newline at end of file diff --git a/apps/assets/templates/assets/system_user_list.html b/apps/assets/templates/assets/system_user_list.html index 77526ff37..ba264541c 100644 --- a/apps/assets/templates/assets/system_user_list.html +++ b/apps/assets/templates/assets/system_user_list.html @@ -26,33 +26,110 @@ +
    +
    + +
    + +
    +
    +
    {% endblock %} {% block custom_foot_js %} {% endblock %} diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py index 6957f5f8a..8484382f8 100644 --- a/apps/assets/urls/api_urls.py +++ b/apps/assets/urls/api_urls.py @@ -2,16 +2,18 @@ from django.conf.urls import url from .. import api from rest_framework import routers +from rest_framework_bulk.routes import BulkRouter app_name = 'assets' -router = routers.DefaultRouter() +router = BulkRouter() router.register(r'v1/asset-groups', api.AssetGroupViewSet, 'asset-group') router.register(r'v1/assets', api.AssetViewSet, 'asset') router.register(r'v1/idc', api.IDCViewSet, 'idc') router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user') router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user') +router.register(r'v1/tags', api.TagViewSet, 'asset-tag') urlpatterns = [ url(r'^v1/assets_bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'), @@ -20,8 +22,31 @@ urlpatterns = [ url(r'^v1/assets/(?P\d+)/groups/$', api.AssetUpdateGroupApi.as_view(), name='asset-update-group'), + url(r'^v1/assets/(?P\d+)/system-users/$', 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\d+)/assets/$', + api.SystemUserUpdateAssetsApi.as_view(), name='systemuser-update-assets'), + + url(r'^v1/system_user/(?P\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\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\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\d+)/assets/$', + api.IDCupdateAssetsApi.as_view(), name='idc-update-assets'), + + url(r'v1/tag/(?P\d+)/assets/$', + api.TagUpdateAssetsApi.as_view(), name='tag-update-assets'), + + ] urlpatterns += router.urls diff --git a/apps/assets/views.py b/apps/assets/views.py index 7070d78bf..f0f759b94 100644 --- a/apps/assets/views.py +++ b/apps/assets/views.py @@ -16,7 +16,7 @@ from django.urls import reverse_lazy from django.contrib.messages.views import SuccessMessageMixin from django.views.generic.detail import DetailView, SingleObjectMixin 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.utils.decorators import method_decorator from django.core.cache import cache @@ -31,803 +31,839 @@ from .hands import AdminUserRequiredMixin class AssetListView(AdminUserRequiredMixin, TemplateView): - template_name = 'assets/asset_list.html' + template_name = 'assets/asset_list.html' - def get_context_data(self, **kwargs): - context = { - 'app': 'Assets', - 'action': 'asset list', - 'tag_list': [(i.id, i.name, i.asset_set.all().count())for i in Tag.objects.all().order_by('name')] - - } - kwargs.update(context) - return super(AssetListView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': 'Assets', + 'action': 'asset list', + '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')], + 'tags': Tag.objects.all().order_by('name') + } + kwargs.update(context) + return super(AssetListView, self).get_context_data(**kwargs) class AssetCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView): - model = Asset - tag_type = 'asset' - form_class = forms.AssetCreateForm - template_name = 'assets/asset_create.html' - success_url = reverse_lazy('assets:asset-list') + model = Asset + tag_type = 'asset' + form_class = forms.AssetCreateForm + template_name = 'assets/asset_create.html' + success_url = reverse_lazy('assets:asset-list') - def form_valid(self, form): - asset = form.save() - asset.created_by = self.request.user.username or 'Admin' - asset.save() - return super(AssetCreateView, self).form_valid(form) + def form_valid(self, form): + asset = form.save() + asset.created_by = self.request.user.username or 'Admin' + asset.save() + return super(AssetCreateView, self).form_valid(form) - def form_invalid(self, form): - if form.errors.get('__all__'): - form.errors['all'] = form.errors.get('__all__') - return super(AssetCreateView, self).form_invalid(form) + def form_invalid(self, form): + if form.errors.get('__all__'): + form.errors['all'] = form.errors.get('__all__') + return super(AssetCreateView, self).form_invalid(form) - def get_context_data(self, **kwargs): - context = { - 'app': 'Assets', - 'action': 'Create asset', - } - kwargs.update(context) - return super(AssetCreateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': 'Assets', + 'action': 'Create asset', + } + kwargs.update(context) + return super(AssetCreateView, self).get_context_data(**kwargs) class AssetModalCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, ListView): - model = Asset - form_class = forms.AssetCreateForm - template_name = 'assets/asset_modal_update.html' - success_url = reverse_lazy('assets:asset-list') + model = Asset + form_class = forms.AssetCreateForm + template_name = 'assets/asset_modal_update.html' + success_url = reverse_lazy('assets:asset-list') - def get_queryset(self): - self.queryset = super(AssetModalCreateView,self).get_queryset() - self.s = self.request.GET.get('plain_id_lists') - if "," in str(self.s): - self.plain_id_lists = [int(x) for x in self.s.split(',')] - else: - self.plain_id_lists = [self.s] - return self.queryset + def get_queryset(self): + self.queryset = super(AssetModalCreateView,self).get_queryset() + self.s = self.request.GET.get('plain_id_lists') + if "," in str(self.s): + self.plain_id_lists = [int(x) for x in self.s.split(',')] + else: + self.plain_id_lists = [self.s] + return self.queryset - def get_context_data(self, **kwargs): - asset_on_list = Asset.objects.filter(id__in = self.plain_id_lists) - context = { - 'app': 'Assets', - 'action': 'Bulk Update asset', - 'assets_on_list': asset_on_list, - 'assets_count': len(asset_on_list), - 'plain_id_lists':self.s, - } - kwargs.update(context) - return super(AssetModalCreateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + asset_on_list = Asset.objects.filter(id__in = self.plain_id_lists) + context = { + 'app': 'Assets', + 'action': 'Bulk Update asset', + 'assets_on_list': asset_on_list, + 'assets_count': len(asset_on_list), + 'plain_id_lists':self.s, + } + kwargs.update(context) + return super(AssetModalCreateView, self).get_context_data(**kwargs) class AssetUpdateView(AdminUserRequiredMixin, UpdateAssetTagsMiXin, UpdateView): - model = Asset - form_class = forms.AssetCreateForm - template_name = 'assets/asset_update.html' - success_url = reverse_lazy('assets:asset-list') - new_form = '' - assets_ids = '' + model = Asset + form_class = forms.AssetCreateForm + template_name = 'assets/asset_update.html' + success_url = reverse_lazy('assets:asset-list') + new_form = '' + assets_ids = '' - def post(self, request, *args, **kwargs): - default_keys = [ - 'csrfmiddlewaretoken', - 'assets_ids', - 'ip', - 'number', - 'hostname', - 'system_users', - 'admin_user', - ] - self.assets_ids = self.request.POST.getlist('assets_ids') - self.new_form = self.request.POST.copy() - for i in default_keys: - if self.new_form.has_key(i): - self.new_form.pop(i) + def post(self, request, *args, **kwargs): + default_keys = [ + 'csrfmiddlewaretoken', + 'assets_ids', + 'ip', + 'number', + 'hostname', + 'system_users', + 'admin_user', + ] + self.assets_ids = self.request.POST.getlist('assets_ids') + self.new_form = self.request.POST.copy() + for i in default_keys: + if self.new_form.has_key(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): - context = { - 'app': 'Assets', - 'action': 'Update asset', - } - kwargs.update(context) - return super(AssetUpdateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': 'Assets', + 'action': 'Update asset', + } + kwargs.update(context) + return super(AssetUpdateView, self).get_context_data(**kwargs) - def form_invalid(self, form): - print(form.errors) - return super(AssetUpdateView, self).form_invalid(form) + def form_invalid(self, form): + print(form.errors) + return super(AssetUpdateView, self).form_invalid(form) - def form_valid(self, form): - asset = form.save(commit=False) + def form_valid(self, form): + asset = form.save(commit=False) - def prn_obj_key(obj_form): - return obj_form.clean().keys() + def prn_obj_key(obj_form): + return obj_form.clean().keys() - for i in prn_obj_key(form): - if i not in self.new_form.keys(): - print i + for i in prn_obj_key(form): + if i not in self.new_form.keys(): + print i - #delattr(asset, '"%s" % i') - #del asset.i - asset.save() - asset.id = 27 - # asset.created_by = self.request.user.username or 'Admin' - asset.save() - asset.id = 28 - asset.save() - return super(AssetUpdateView, self).form_valid(form) + #delattr(asset, '"%s" % i') + #del asset.i + asset.save() + asset.id = 27 + # asset.created_by = self.request.user.username or 'Admin' + asset.save() + asset.id = 28 + asset.save() + return super(AssetUpdateView, self).form_valid(form) class AssetDeleteView(DeleteView): - model = Asset - template_name = 'assets/delete_confirm.html' - success_url = reverse_lazy('assets:asset-list') + model = Asset + template_name = 'assets/delete_confirm.html' + success_url = reverse_lazy('assets:asset-list') class AssetDetailView(DetailView): - model = Asset - context_object_name = 'asset' - template_name = 'assets/asset_detail.html' + model = Asset + context_object_name = 'asset' + template_name = 'assets/asset_detail.html' - def get_context_data(self, **kwargs): - asset_groups = self.object.groups.all() - system_users = self.object.system_users.all() - context = { - 'app': 'Assets', - 'action': 'Asset detail', - 'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all() - if asset_group not in asset_groups], - 'asset_groups': asset_groups, - 'system_users_remain': [system_user for system_user in SystemUser.objects.all() - if system_user not in system_users], - 'system_users': system_users, - } - kwargs.update(context) - return super(AssetDetailView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + asset_groups = self.object.groups.all() + system_users = self.object.system_users.all() + context = { + 'app': 'Assets', + 'action': 'Asset detail', + 'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all() + if asset_group not in asset_groups], + 'asset_groups': asset_groups, + 'system_users_remain': [system_user for system_user in SystemUser.objects.all() + if system_user not in system_users], + 'system_users': system_users, + } + kwargs.update(context) + return super(AssetDetailView, self).get_context_data(**kwargs) class AssetModalListView(AdminUserRequiredMixin, ListView): - paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - model = Asset - context_object_name = 'asset_modal_list' - template_name = 'assets/asset_modal_list.html' + paginate_by = settings.CONFIG.DISPLAY_PER_PAGE + model = Asset + context_object_name = 'asset_modal_list' + template_name = 'assets/asset_modal_list.html' - def get_context_data(self, **kwargs): - group_id = self.request.GET.get('group_id') - tag_id = self.request.GET.get('tag_id') - plain_id_lists = self.request.GET.get('plain_id_lists') - self.s = self.request.GET.get('plain_id_lists') - if "," in str(self.s): - self.plain_id_lists = [int(x) for x in self.s.split(',')] - else: - self.plain_id_lists = [self.s] + def get_context_data(self, **kwargs): + group_id = self.request.GET.get('group_id') + tag_id = self.request.GET.get('tag_id') + plain_id_lists = self.request.GET.get('plain_id_lists') + self.s = self.request.GET.get('plain_id_lists') + if "," in str(self.s): + self.plain_id_lists = [int(x) for x in self.s.split(',')] + else: + self.plain_id_lists = [self.s] - if plain_id_lists: - if "," in str(self.s): - plain_id_lists = [int(x) for x in self.s.split(',')] - else: - plain_id_lists = [int(self.s)] - context = { - 'all_assets' :plain_id_lists - } - kwargs.update(context) - if group_id: - group = AssetGroup.objects.get(id=group_id) - context = { - 'all_assets': [x.id for x in group.assets.all()] - } - kwargs.update(context) - if tag_id: - tag = Tag.objects.get(id=tag_id) - context = { - 'all_assets': [x.id for x in tag.asset_set.all()] - } - kwargs.update(context) - return super(AssetModalListView, self).get_context_data(**kwargs) + if plain_id_lists: + if "," in str(self.s): + plain_id_lists = [int(x) for x in self.s.split(',')] + else: + plain_id_lists = [int(self.s)] + context = { + 'all_assets' :plain_id_lists + } + kwargs.update(context) + if group_id: + group = AssetGroup.objects.get(id=group_id) + context = { + 'all_assets': [x.id for x in group.assets.all()] + } + kwargs.update(context) + if tag_id: + tag = Tag.objects.get(id=tag_id) + context = { + 'all_assets': [x.id for x in tag.asset_set.all()] + } + kwargs.update(context) + return super(AssetModalListView, self).get_context_data(**kwargs) class AssetGroupCreateView(AdminUserRequiredMixin, CreateView): - model = AssetGroup - form_class = forms.AssetGroupForm - template_name = 'assets/asset_group_create.html' - success_url = reverse_lazy('assets:asset-group-list') - #ordering = '-id' + model = AssetGroup + form_class = forms.AssetGroupForm + template_name = 'assets/asset_group_create.html' + success_url = reverse_lazy('assets:asset-group-list') + #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): - context = { - 'app': _('Assets'), - 'action': _('Create asset group'), - 'assets_count': 0, - } - kwargs.update(context) - return super(AssetGroupCreateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('Assets'), + 'action': _('Create asset group'), + 'assets_count': 0, + } + kwargs.update(context) + return super(AssetGroupCreateView, self).get_context_data(**kwargs) - def form_valid(self, form): - asset_group = form.save() - 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] - asset_group.created_by = self.request.user.username or 'Admin' - asset_group.assets.add(*tuple(assets)) - asset_group.save() - return super(AssetGroupCreateView, self).form_valid(form) + def form_valid(self, form): + asset_group = form.save() + 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] + asset_group.created_by = self.request.user.username or 'Admin' + asset_group.assets.add(*tuple(assets)) + asset_group.save() + return super(AssetGroupCreateView, self).form_valid(form) class AssetGroupListView(AdminUserRequiredMixin, TemplateView): - template_name = 'assets/asset_group_list.html' + template_name = 'assets/asset_group_list.html' - def get_context_data(self, **kwargs): - context = { - 'app': _('Assets'), - 'action': _('Asset group list'), - 'keyword': self.request.GET.get('keyword', '') - } - kwargs.update(context) - return super(AssetGroupListView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('Assets'), + 'action': _('Asset group list'), + 'assets': Asset.objects.all(), + 'system_users': SystemUser.objects.all(), + 'keyword': self.request.GET.get('keyword', '') + } + kwargs.update(context) + return super(AssetGroupListView, self).get_context_data(**kwargs) class AssetGroupDetailView(AdminUserRequiredMixin, DetailView): - model = AssetGroup - template_name = 'assets/asset_group_detail.html' - context_object_name = 'asset_group' + model = AssetGroup + template_name = 'assets/asset_group_detail.html' + context_object_name = 'asset_group' - def get_context_data(self, **kwargs): - assets_remain = Asset.objects.exclude(id__in=self.object.assets.all()) - system_users = self.object.system_users.all() - system_users_remain = SystemUser.objects.exclude(id__in=system_users) - context = { - 'app': _('Assets'), - 'action': _('Asset group detail'), - 'assets_remain': assets_remain, - 'system_users': system_users, - 'system_users_remain': system_users_remain, - } - kwargs.update(context) - return super(AssetGroupDetailView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + assets_remain = Asset.objects.exclude(id__in=self.object.assets.all()) + system_users = self.object.system_users.all() + system_users_remain = SystemUser.objects.exclude(id__in=system_users) + context = { + 'app': _('Assets'), + 'action': _('Asset group detail'), + 'assets_remain': assets_remain, + 'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain], + 'system_users': system_users, + 'system_users_remain': system_users_remain, + } + kwargs.update(context) + return super(AssetGroupDetailView, self).get_context_data(**kwargs) class AssetGroupUpdateView(AdminUserRequiredMixin, UpdateView): - model = AssetGroup - form_class = forms.AssetGroupForm - template_name = 'assets/asset_group_create.html' - success_url = reverse_lazy('assets:asset-group-list') + model = AssetGroup + form_class = forms.AssetGroupForm + template_name = 'assets/asset_group_create.html' + success_url = reverse_lazy('assets:asset-group-list') - def get(self, request, *args, **kwargs): - self.object = self.get_object(queryset=AssetGroup.objects.all()) - return super(AssetGroupUpdateView, self).get(request, *args, **kwargs) + def get(self, request, *args, **kwargs): + self.object = self.get_object(queryset=AssetGroup.objects.all()) + return super(AssetGroupUpdateView, self).get(request, *args, **kwargs) - def get_context_data(self, **kwargs): - assets_all = self.object.assets.all() - context = { - 'app': _('Assets'), - 'action': _('Create asset group'), - 'assets_on_list': assets_all, - 'assets_count': len(assets_all), - 'group_id':self.object.id, - } - kwargs.update(context) - return super(AssetGroupUpdateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + assets_all = self.object.assets.all() + context = { + 'app': _('Assets'), + 'action': _('Create asset group'), + 'assets_on_list': assets_all, + 'assets_count': len(assets_all), + 'group_id':self.object.id, + } + kwargs.update(context) + return super(AssetGroupUpdateView, self).get_context_data(**kwargs) class AssetGroupDeleteView(AdminUserRequiredMixin, DeleteView): - template_name = 'assets/delete_confirm.html' - model = AssetGroup - success_url = reverse_lazy('assets:asset-group-list') + template_name = 'assets/delete_confirm.html' + model = AssetGroup + success_url = reverse_lazy('assets:asset-group-list') class IDCListView(AdminUserRequiredMixin, TemplateView): - template_name = 'assets/idc_list.html' + template_name = 'assets/idc_list.html' - def get_context_data(self, **kwargs): - context = { - 'app': _('Assets'), - 'action': _('IDC list'), - # 'keyword': self.request.GET.get('keyword', '') - } - kwargs.update(context) - return super(IDCListView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('Assets'), + 'action': _('IDC list'), + # 'keyword': self.request.GET.get('keyword', '') + } + kwargs.update(context) + return super(IDCListView, self).get_context_data(**kwargs) class IDCCreateView(AdminUserRequiredMixin, CreateView): - model = IDC - form_class = forms.IDCForm - template_name = 'assets/idc_create_update.html' - success_url = reverse_lazy('assets:idc-list') + model = IDC + form_class = forms.IDCForm + template_name = 'assets/idc_create_update.html' + success_url = reverse_lazy('assets:idc-list') - def get_context_data(self, **kwargs): - context = { - 'app': _('assets'), - 'action': _('Create IDC'), - } - kwargs.update(context) - return super(IDCCreateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('assets'), + 'action': _('Create IDC'), + } + kwargs.update(context) + return super(IDCCreateView, self).get_context_data(**kwargs) - def form_valid(self, form): - IDC = form.save(commit=False) - IDC.created_by = self.request.user.username or 'System' - IDC.save() - # IDC_add_success_next(user) - return super(IDCCreateView, self).form_valid(form) + def form_valid(self, form): + IDC = form.save(commit=False) + IDC.created_by = self.request.user.username or 'System' + IDC.save() + # IDC_add_success_next(user) + return super(IDCCreateView, self).form_valid(form) class IDCUpdateView(AdminUserRequiredMixin, UpdateView): - model = IDC - form_class = forms.IDCForm - template_name = 'assets/idc_create_update.html' - context_object_name = 'idc' - success_url = reverse_lazy('assets:idc-list') + model = IDC + form_class = forms.IDCForm + template_name = 'assets/idc_create_update.html' + context_object_name = 'idc' + success_url = reverse_lazy('assets:idc-list') - def form_valid(self, form): - idc = form.save(commit=False) - idc.save() - return super(IDCUpdateView, self).form_valid(form) + def form_valid(self, form): + idc = form.save(commit=False) + idc.save() + return super(IDCUpdateView, self).form_valid(form) - def get_context_data(self, **kwargs): - context = { - 'app': _('assets'), - 'action': _('Update IDC'), - } - kwargs.update(context) - return super(IDCUpdateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('assets'), + 'action': _('Update IDC'), + } + kwargs.update(context) + return super(IDCUpdateView, self).get_context_data(**kwargs) class IDCDetailView(AdminUserRequiredMixin, DetailView): - model = IDC - template_name = 'assets/idc_detail.html' - context_object_name = 'idc' + model = IDC + template_name = 'assets/idc_detail.html' + context_object_name = 'idc' class IDCAssetsView(AdminUserRequiredMixin, DetailView): - model = IDC - template_name = 'assets/idc_assets.html' - context_object_name = 'idc' + model = IDC + template_name = 'assets/idc_assets.html' + 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): - model = IDC - template_name = 'assets/delete_confirm.html' - success_url = reverse_lazy('assets:idc-list') + model = IDC + template_name = 'assets/delete_confirm.html' + success_url = reverse_lazy('assets:idc-list') class AdminUserListView(AdminUserRequiredMixin, TemplateView): - model = AdminUser - # paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - # context_object_name = 'admin_user_list' - template_name = 'assets/admin_user_list.html' + model = AdminUser + # paginate_by = settings.CONFIG.DISPLAY_PER_PAGE + # context_object_name = 'admin_user_list' + template_name = 'assets/admin_user_list.html' - def get_context_data(self, **kwargs): - context = { - 'app': _('Assets'), - 'action': _('Admin user list'), - # 'keyword': self.request.GET.get('keyword', '') - } - kwargs.update(context) - return super(AdminUserListView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('Assets'), + 'action': _('Admin user list'), + # 'keyword': self.request.GET.get('keyword', '') + } + kwargs.update(context) + return super(AdminUserListView, self).get_context_data(**kwargs) - # def get_queryset(self): - # Todo: Default order by lose asset connection num - # self.queryset = super(AdminUserListView, self).get_queryset() - # self.keyword = keyword = self.request.GET.get('keyword', '') - # self.sort = sort = self.request.GET.get('sort', '-date_created') - # - # if keyword: - # self.queryset = self.queryset.filter(Q(name__icontains=keyword) | - # Q(comment__icontains=keyword)) - # - # if sort: - # self.queryset = self.queryset.order_by(sort) - # return self.queryset + # def get_queryset(self): + # Todo: Default order by lose asset connection num + # self.queryset = super(AdminUserListView, self).get_queryset() + # self.keyword = keyword = self.request.GET.get('keyword', '') + # self.sort = sort = self.request.GET.get('sort', '-date_created') + # + # if keyword: + # self.queryset = self.queryset.filter(Q(name__icontains=keyword) | + # Q(comment__icontains=keyword)) + # + # if sort: + # self.queryset = self.queryset.order_by(sort) + # return self.queryset class AdminUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView): - model = AdminUser - form_class = forms.AdminUserForm - template_name = 'assets/admin_user_create_update.html' - success_url = reverse_lazy('assets:admin-user-list') + model = AdminUser + form_class = forms.AdminUserForm + template_name = 'assets/admin_user_create_update.html' + success_url = reverse_lazy('assets:admin-user-list') - def get_context_data(self, **kwargs): - context = { - 'app': 'assets', - 'action': 'Create admin user' - } - kwargs.update(context) - return super(AdminUserCreateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': 'assets', + 'action': 'Create admin user' + } + kwargs.update(context) + return super(AdminUserCreateView, self).get_context_data(**kwargs) - def get_success_message(self, cleaned_data): - success_message = _('Create admin user %s successfully.' % - ( - reverse_lazy('assets:admin-user-detail', kwargs={'pk': self.object.pk}), - self.object.name, - )) - return success_message + def get_success_message(self, cleaned_data): + success_message = _('Create admin user %s successfully.' % + ( + reverse_lazy('assets:admin-user-detail', kwargs={'pk': self.object.pk}), + self.object.name, + )) + return success_message - def form_invalid(self, form): - return super(AdminUserCreateView, self).form_invalid(form) + def form_invalid(self, form): + return super(AdminUserCreateView, self).form_invalid(form) class AdminUserUpdateView(AdminUserRequiredMixin, UpdateView): - model = AdminUser - form_class = forms.AdminUserForm - template_name = 'assets/admin_user_create_update.html' + model = AdminUser + form_class = forms.AdminUserForm + template_name = 'assets/admin_user_create_update.html' - def get_context_data(self, **kwargs): - context = { - 'app': 'assets', - 'action': 'Update admin user' - } - kwargs.update(context) - return super(AdminUserUpdateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': 'assets', + 'action': 'Update admin user' + } + kwargs.update(context) + return super(AdminUserUpdateView, self).get_context_data(**kwargs) - def get_success_url(self): - success_url = reverse_lazy('assets:admin-user-detail', pk=self.object.pk) - return success_url + def get_success_url(self): + success_url = reverse_lazy('assets:admin-user-detail', pk=self.object.pk) + return success_url class AdminUserDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView): - paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - template_name = 'assets/admin_user_detail.html' - context_object_name = 'admin_user' + paginate_by = settings.CONFIG.DISPLAY_PER_PAGE + template_name = 'assets/admin_user_detail.html' + context_object_name = 'admin_user' - def get(self, request, *args, **kwargs): - self.object = self.get_object(queryset=AdminUser.objects.all()) - return super(AdminUserDetailView, self).get(request, *args, **kwargs) + def get(self, request, *args, **kwargs): + self.object = self.get_object(queryset=AdminUser.objects.all()) + return super(AdminUserDetailView, self).get(request, *args, **kwargs) - # Todo: queryset default order by connectivity, need ops support - def get_queryset(self): - return self.object.assets.all() + # Todo: queryset default order by connectivity, need ops support + def get_queryset(self): + return self.object.assets.all() - def get_context_data(self, **kwargs): - context = { - 'app': 'assets', - 'action': 'Admin user detail' - } - kwargs.update(context) - return super(AdminUserDetailView, self).get_context_data(**kwargs) + # def get_asset_groups(self): + # return self.object.asset_groups.all() + + def get_context_data(self, **kwargs): + asset_groups = AssetGroup.objects.all() + assets = self.get_queryset() + 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): - model = AdminUser - template_name = 'assets/delete_confirm.html' - success_url = reverse_lazy('assets:admin-user-list') + model = AdminUser + template_name = 'assets/delete_confirm.html' + success_url = reverse_lazy('assets:admin-user-list') class SystemUserListView(AdminUserRequiredMixin, TemplateView): - template_name = 'assets/system_user_list.html' + template_name = 'assets/system_user_list.html' - def get_context_data(self, **kwargs): - context = { - 'app': _('Assets'), - 'action': _('System user list'), - } - kwargs.update(context) - return super(SystemUserListView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('Assets'), + 'action': _('System user list'), + } + kwargs.update(context) + return super(SystemUserListView, self).get_context_data(**kwargs) class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView): - model = SystemUser - form_class = forms.SystemUserForm - template_name = 'assets/system_user_create_update.html' - success_url = reverse_lazy('assets:system-user-list') + model = SystemUser + form_class = forms.SystemUserForm + template_name = 'assets/system_user_create_update.html' + success_url = reverse_lazy('assets:system-user-list') - def get_context_data(self, **kwargs): - context = { - 'app': _('Assets'), - 'action': _('Create system user'), - } - kwargs.update(context) - return super(SystemUserCreateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('Assets'), + 'action': _('Create system user'), + } + kwargs.update(context) + return super(SystemUserCreateView, self).get_context_data(**kwargs) - def get_success_message(self, cleaned_data): - success_message = _('Create system user %s successfully.' % - ( - reverse_lazy('assets:system-user-detail', kwargs={'pk': self.object.pk}), - self.object.name, - )) + def get_success_message(self, cleaned_data): + success_message = _('Create system user %s successfully.' % + ( + reverse_lazy('assets:system-user-detail', kwargs={'pk': self.object.pk}), + self.object.name, + )) - return success_message + return success_message class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView): - model = SystemUser - form_class = forms.SystemUserForm - template_name = 'assets/system_user_create_update.html' + model = SystemUser + form_class = forms.SystemUserForm + template_name = 'assets/system_user_create_update.html' - def get_context_data(self, **kwargs): - context = { - 'app': _('Assets'), - 'action': _('Update system user') - } - kwargs.update(context) - return super(SystemUserUpdateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('Assets'), + 'action': _('Update system user') + } + kwargs.update(context) + return super(SystemUserUpdateView, self).get_context_data(**kwargs) - def get_success_url(self): - success_url = reverse_lazy('assets:system-user-detail', kwargs={'pk': self.object.pk}) - return success_url + def get_success_url(self): + success_url = reverse_lazy('assets:system-user-detail', kwargs={'pk': self.object.pk}) + return success_url class SystemUserDetailView(AdminUserRequiredMixin, DetailView): - template_name = 'assets/system_user_detail.html' - context_object_name = 'system_user' - model = SystemUser + template_name = 'assets/system_user_detail.html' + context_object_name = 'system_user' + model = SystemUser - def get_context_data(self, **kwargs): - context = { - 'app': _('Assets'), - 'action': _('System user detail') - } - kwargs.update(context) - return super(SystemUserDetailView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('Assets'), + 'action': _('System user detail') + } + kwargs.update(context) + return super(SystemUserDetailView, self).get_context_data(**kwargs) class SystemUserDeleteView(AdminUserRequiredMixin, DeleteView): - model = SystemUser - template_name = 'assets/delete_confirm.html' - success_url = reverse_lazy('assets:system-user-list') + model = SystemUser + template_name = 'assets/delete_confirm.html' + success_url = reverse_lazy('assets:system-user-list') class SystemUserAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView): - paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - template_name = 'assets/system_user_asset.html' - context_object_name = 'system_user' + paginate_by = settings.CONFIG.DISPLAY_PER_PAGE + template_name = 'assets/system_user_asset.html' + context_object_name = 'system_user' - def get(self, request, *args, **kwargs): - self.object = self.get_object(queryset=SystemUser.objects.all()) - return super(SystemUserAssetView, self).get(request, *args, **kwargs) + def get(self, request, *args, **kwargs): + self.object = self.get_object(queryset=SystemUser.objects.all()) + return super(SystemUserAssetView, self).get(request, *args, **kwargs) - def get_asset_groups(self): - return self.object.asset_groups.all() + def get_asset_groups(self): + return self.object.asset_groups.all() - # Todo: queryset default order by connectivity, need ops support - def get_queryset(self): - return list(self.object.get_assets()) + # Todo: queryset default order by connectivity, need ops support + def get_queryset(self): + return list(self.object.get_assets()) - def get_context_data(self, **kwargs): - asset_groups = self.get_asset_groups() - assets = self.get_queryset() - context = { - 'app': 'assets', - 'action': 'System user asset', - '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(SystemUserAssetView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + asset_groups = self.get_asset_groups() + assets = self.get_queryset() + context = { + 'app': 'assets', + 'action': 'System user asset', + '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(SystemUserAssetView, self).get_context_data(**kwargs) class TagView(ListView): - context_object_name = 'asset_list' - template_name = 'assets/asset_list.html' + context_object_name = 'asset_list' + template_name = 'assets/asset_list.html' - def get_queryset(self): - asset_list = Asset.objects.filter(tags=self.kwargs['tag_id']) - return asset_list + def get_queryset(self): + asset_list = Asset.objects.filter(tags=self.kwargs['tag_id']) + return asset_list - def get_context_data(self, **kwargs): - kwargs['app'] = 'Assets' - 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_id'] = self.kwargs['tag_id'] - return super(TagView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + kwargs['app'] = 'Assets' + 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_id'] = self.kwargs['tag_id'] + return super(TagView, self).get_context_data(**kwargs) class TagsListView(AdminUserRequiredMixin, ListView): - model = Tag - paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - context_object_name = 'asset_tags_list' - template_name = 'assets/asset_tags_list.html' - ordering = '-id' + model = Tag + paginate_by = settings.CONFIG.DISPLAY_PER_PAGE + context_object_name = 'asset_tags_list' + template_name = 'assets/asset_tags_list.html' + ordering = '-id' - def get_context_data(self, **kwargs): - context = { - 'app': _('Tag'), - 'action': _('Asset Tags list'), - 'keyword': self.request.GET.get('keyword', '') - } - kwargs.update(context) - return super(TagsListView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('Tag'), + 'action': _('Asset Tags list'), + 'keyword': self.request.GET.get('keyword', '') + } + kwargs.update(context) + return super(TagsListView, self).get_context_data(**kwargs) -class AssetTagCreateView(AdminUserRequiredMixin, CreateView): - model = Tag - form_class = forms.AssetTagForm - template_name = 'assets/asset_tag_create.html' - success_url = reverse_lazy('assets:asset-tag-list') - #ordering = '-id' +class AssetTagCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView): + model = Tag + form_class = forms.AssetTagForm + template_name = 'assets/asset_tag_create.html' + success_url = reverse_lazy('assets:asset-tag-list') + #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): - context = { - 'app': _('Tag'), - 'action': _('Asset Tags list'), - 'assets_count': 0, - } - kwargs.update(context) - return super(AssetTagCreateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + context = { + 'app': _('Tag'), + 'action': _('Asset Tags list'), + 'assets_count': 0, + } + kwargs.update(context) + return super(AssetTagCreateView, self).get_context_data(**kwargs) - def form_valid(self, form): - asset_tag = form.save() - 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] - asset_tag.created_by = self.request.user.username or 'Admin' - asset_tag.asset_set.add(*tuple(assets)) - asset_tag.save() - return super(AssetTagCreateView, self).form_valid(form) + def form_valid(self, form): + asset_tag = form.save() + 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] + asset_tag.created_by = self.request.user.username or 'Admin' + asset_tag.assets.add(*tuple(assets)) + asset_tag.save() + return super(AssetTagCreateView, self).form_valid(form) class AssetTagDetailView(SingleObjectMixin, AdminUserRequiredMixin, ListView): - template_name = 'assets/asset_tag_detail.html' - paginate_by = settings.CONFIG.DISPLAY_PER_PAGE + template_name = 'assets/asset_tag_detail.html' + paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - def get(self, request, *args, **kwargs): - self.object = self.get_object(queryset=Tag.objects.all()) - return super(AssetTagDetailView, self).get(request, *args, **kwargs) - def get_queryset(self): - return self.object.asset_set.all() + def get(self, request, *args, **kwargs): + self.object = self.get_object(queryset=Tag.objects.all()) + return super(AssetTagDetailView, self).get(request, *args, **kwargs) - def get_context_data(self, **kwargs): - context = { - 'app': _('Tag'), - 'action': _('Asset Tags detail'), - 'asset_tag': self.object, - } - kwargs.update(context) - return super(AssetTagDetailView, self).get_context_data(**kwargs) + def get_queryset(self): + return self.object.assets.all() + + def get_context_data(self, **kwargs): + assets_remain = Asset.objects.exclude(id__in=self.object.assets.all()) + context = { + 'app': _('Tag'), + 'action': _('Asset Tags detail'), + 'asset_tag': self.object, + 'assets_remain': assets_remain, + '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): - model = Tag - form_class = forms.AssetTagForm - template_name = 'assets/asset_tag_create.html' - success_url = reverse_lazy('assets:asset-tag-list') + model = Tag + form_class = forms.AssetTagForm + template_name = 'assets/asset_tag_create.html' + success_url = reverse_lazy('assets:asset-tag-list') - def get(self, request, *args, **kwargs): - self.object = self.get_object(queryset=Tag.objects.all()) - return super(AssetTagUpdateView, self).get(request, *args, **kwargs) + def get(self, request, *args, **kwargs): + self.object = self.get_object(queryset=Tag.objects.all()) + return super(AssetTagUpdateView, self).get(request, *args, **kwargs) - def get_context_data(self, **kwargs): - assets_all = self.object.asset_set.all() - context = { - 'app': _('Tag'), - 'action': _('Asset Tags detail'), - 'assets_count': len(assets_all), - 'assets_on_list': assets_all, - 'tag_id':self.object.id, - } - kwargs.update(context) - return super(AssetTagUpdateView, self).get_context_data(**kwargs) + def get_context_data(self, **kwargs): + assets_all = self.object.assets.all() + context = { + 'app': _('Tag'), + 'action': _('Asset Tags detail'), + 'assets_count': len(assets_all), + 'assets_on_list': assets_all, + 'tag_id':self.object.id, + } + kwargs.update(context) + return super(AssetTagUpdateView, self).get_context_data(**kwargs) class AssetTagDeleteView(AdminUserRequiredMixin, DeleteView): - template_name = 'assets/delete_confirm.html' - model = Tag - success_url = reverse_lazy('assets:asset-tag-list') + template_name = 'assets/delete_confirm.html' + model = Tag + success_url = reverse_lazy('assets:asset-tag-list') @method_decorator(csrf_exempt, name='dispatch') class AssetExportView(View): - @staticmethod - def get_asset_attr(asset, attr): - if attr in ['admin_user', 'idc']: - return getattr(asset, attr).name - elif attr in ['status', 'type', 'env']: - return getattr(asset, 'get_{}_display'.format(attr))() - else: - return getattr(asset, attr) + @staticmethod + def get_asset_attr(asset, attr): + if attr in ['admin_user', 'idc']: + return getattr(asset, attr) + # elif attr in ['status', 'type', 'env']: + # return getattr(asset, 'get_{}_display'.format(attr)) + else: + return getattr(asset, attr) - def get(self, request, *args, **kwargs): - spm = request.GET.get('spm', '') - assets_id = cache.get(spm) - if not assets_id and not isinstance(assets_id, list): - return HttpResponse('May be expired', status=404) + def get(self, request, *args, **kwargs): + spm = request.GET.get('spm', '') + assets_id = cache.get(spm) + if not assets_id and not isinstance(assets_id, list): + return HttpResponse('May be expired', status=404) - assets = Asset.objects.filter(id__in=assets_id) - wb = Workbook() - ws = wb.active - ws.title = 'Asset' - header = ['hostname', 'ip', 'port', 'admin_user', 'idc', 'cpu', 'memory', 'disk', - 'mac_address', 'other_ip', 'remote_card_ip', 'os', 'cabinet_no', - 'cabinet_pos', 'number', 'status', 'type', 'env', 'sn', 'comment'] - ws.append(header) + assets = Asset.objects.filter(id__in=assets_id) + wb = Workbook() + ws = wb.active + ws.title = 'Asset' + header = ['hostname', 'ip', 'port', 'admin_user', 'idc', 'cpu', 'memory', 'disk', + 'mac_address', 'other_ip', 'remote_card_ip', 'os', 'cabinet_no', + 'cabinet_pos', 'number', 'status', 'type', 'env', 'sn', 'comment'] + ws.append(header) - for asset in assets: - ws.append([self.get_asset_attr(asset, attr) for attr in header]) + for asset in assets: + 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 - return response - def post(self, request, *args, **kwargs): - try: - assets_id = json.loads(request.body).get('assets_id', []) - print(assets_id) - except ValueError: - return HttpResponse('Json object not valid', status=400) - spm = uuid.uuid4().get_hex() - cache.set(spm, assets_id, 300) - url = reverse('assets:asset-export') + '?spm=%s' % spm - return JsonResponse({'redirect': url}) + 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 + return response + + def post(self, request, *args, **kwargs): + try: + assets_id = json.loads(request.body).get('assets_id', []) + except ValueError: + return HttpResponse('Json object not valid', status=400) + spm = uuid.uuid4().get_hex() + cache.set(spm, assets_id, 300) + url = reverse('assets:asset-export') + '?spm=%s' % spm + print url + return HttpResponse({'redirect': url}) class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView): - form_class = forms.FileForm + form_class = forms.FileForm - def form_valid(self, form): - try: - wb = load_workbook(form.cleaned_data['file']) - ws = wb.get_active_sheet() - except Exception as e: - print(e) - data = {'valid': False, 'msg': 'Not a valid Excel file'} - return self.render_json_response(data) + def form_valid(self, form): + try: + wb = load_workbook(form.cleaned_data['file']) + ws = wb.get_active_sheet() + except Exception as e: + print(e) + data = {'valid': False, 'msg': 'Not a valid Excel file'} + return self.render_json_response(data) - rows = ws.rows - header_all = ['hostname', 'ip', 'port', 'admin_user', 'idc', 'cpu', 'memory', 'disk', - 'mac_address', 'other_ip', 'remote_card_ip', 'os', 'cabinet_no', - 'cabinet_pos', 'number', 'status', 'type', 'env', 'sn', 'comment'] - header_min = ['hostname', 'ip', 'port', 'admin_user', 'comment'] - header = [col.value for col in next(rows)] - 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'} - return self.render_json_response(data) + rows = ws.rows + header_all = ['hostname', 'ip', 'port', 'admin_user', 'idc', 'cpu', 'memory', 'disk', + 'mac_address', 'other_ip', 'remote_card_ip', 'os', 'cabinet_no', + 'cabinet_pos', 'number', 'status', 'type', 'env', 'sn', 'comment'] + header_min = ['hostname', 'ip', 'port', 'admin_user', 'comment'] + header = [col.value for col in next(rows)] + 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'} + return self.render_json_response(data) - created = [] - updated = [] - failed = [] - for row in rows: - asset_dict = dict(zip(header, [col.value for col in row])) - if asset_dict.get('admin_user', None): - admin_user = get_object_or_none(AdminUser, name=asset_dict['admin_user']) - asset_dict['admin_user'] = admin_user + created = [] + updated = [] + failed = [] + for row in rows: + asset_dict = dict(zip(header, [col.value for col in row])) + if asset_dict.get('admin_user', None): + admin_user = get_object_or_none(AdminUser, name=asset_dict['admin_user']) + asset_dict['admin_user'] = admin_user - if asset_dict.get('idc'): - idc = get_object_or_none(IDC, name=asset_dict['idc']) - asset_dict['idc'] = idc + if asset_dict.get('idc'): + idc = get_object_or_none(IDC, name=asset_dict['idc']) + asset_dict['idc'] = idc - if asset_dict.get('type'): - 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_dict['type'] = asset_type + if asset_dict.get('type'): + 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_dict['type'] = asset_type - if asset_dict.get('status'): - asset_display_status_map = dict(zip(dict(Asset.STATUS_CHOICES).values(), - dict(Asset.STATUS_CHOICES).keys())) - asset_status = asset_display_status_map.get(asset_dict['status'], 'In use') - asset_dict['status'] = asset_status + if asset_dict.get('status'): + asset_display_status_map = dict(zip(dict(Asset.STATUS_CHOICES).values(), + dict(Asset.STATUS_CHOICES).keys())) + asset_status = asset_display_status_map.get(asset_dict['status'], 'In use') + asset_dict['status'] = asset_status - if asset_dict.get('env'): - asset_display_env_map = dict(zip(dict(Asset.ENV_CHOICES).values(), - dict(Asset.ENV_CHOICES).keys())) - asset_env = asset_display_env_map.get(asset_dict['env'], 'Prod') - asset_dict['env'] = asset_env + if asset_dict.get('env'): + asset_display_env_map = dict(zip(dict(Asset.ENV_CHOICES).values(), + dict(Asset.ENV_CHOICES).keys())) + asset_env = asset_display_env_map.get(asset_dict['env'], 'Prod') + asset_dict['env'] = asset_env - try: - Asset.objects.create(**asset_dict) - created.append(asset_dict['ip']) - except IntegrityError as e: - asset = Asset.objects.filter(ip=asset_dict['ip'], port=asset_dict['port']) - if not asset: - failed.append(asset_dict['ip']) - continue - asset.update(**asset_dict) - updated.append(asset_dict['ip']) - except TypeError as e: - print(e) - failed.append(asset_dict['ip']) + try: + Asset.objects.create(**asset_dict) + created.append(asset_dict['ip']) + except IntegrityError as e: + asset = Asset.objects.filter(ip=asset_dict['ip'], port=asset_dict['port']) + if not asset: + failed.append(asset_dict['ip']) + continue + asset.update(**asset_dict) + updated.append(asset_dict['ip']) + except TypeError as e: + print(e) + failed.append(asset_dict['ip']) - data = { - 'created': created, - 'created_info': 'Created {}'.format(len(created)), - 'updated': updated, - 'updated_info': 'Updated {}'.format(len(updated)), - 'failed': failed, - 'failed_info': 'Failed {}'.format(len(failed)), - 'valid': True, - 'msg': 'Created: {}. Updated: {}, Error: {}'.format(len(created), len(updated), len(failed)) - } - return self.render_json_response(data) + data = { + 'created': created, + 'created_info': 'Created {}'.format(len(created)), + 'updated': updated, + 'updated_info': 'Updated {}'.format(len(updated)), + 'failed': failed, + 'failed_info': 'Failed {}'.format(len(failed)), + 'valid': True, + 'msg': 'Created: {}. Updated: {}, Error: {}'.format(len(created), len(updated), len(failed)) + } + return self.render_json_response(data)