Merge with master

pull/530/head
ibuler 2017-01-07 22:34:12 +08:00
commit 49861b6a84
26 changed files with 2226 additions and 559 deletions

View File

@ -17,21 +17,23 @@
~ 快速开始 ~ 快速开始
``` ```
pip install -r requirements.txt pip install -r requirements.txt # Install pip module
cp config-example.py config.py yum -y install `cat rpm_requirements.txt` # Install rpm package
cd apps && python manage.py makemigrations cp config-example.py config.py # Prepaire config from example config
python manage.py migrate cd apps && python manage.py makemigrations # Make migrations for django
python manage.py loaddata init python manage.py migrate # Migrate ORM to database
python manage.py loadata fake python manage.py loaddata init # Init some data
python manage.py loaddata fake # Generake some fake data
yum -y install redis && service redis start # Or install redis docker yum -y install redis && service redis start # Or install redis docker
python manage.py runserver 0.0.0.0:80 python manage.py runserver 0.0.0.0:80 # Run it
``` ```

View File

@ -4,41 +4,48 @@ from rest_framework import viewsets, generics, mixins
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework_bulk import BulkModelViewSet, BulkDestroyAPIView
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin, ListBulkCreateUpdateDestroyAPIView from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin, ListBulkCreateUpdateDestroyAPIView
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from common.mixins import IDInFilterMixin from common.mixins import IDInFilterMixin
from common.utils import get_object_or_none, signer from common.utils import get_object_or_none, signer
from .hands import IsSuperUserOrAppUser, IsSuperUser from .hands import IsSuperUser, IsAppUser
from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser from .models import AssetGroup, Asset, IDC, SystemUser, AdminUser, Tag
from . import serializers from . import serializers
class AssetViewSet(IDInFilterMixin, viewsets.ModelViewSet): class AssetViewSet(IDInFilterMixin, BulkModelViewSet):
"""API endpoint that allows Asset to be viewed or edited.""" """API endpoint that allows Asset to be viewed or edited."""
queryset = Asset.objects.all() queryset = Asset.objects.all()
serializer_class = serializers.AssetSerializer serializer_class = serializers.AssetSerializer
filter_fields = ('id', 'ip', 'hostname') permission_classes = (IsSuperUser,)
permission_classes = (IsSuperUserOrAppUser,)
def get_queryset(self): def get_queryset(self):
queryset = super(AssetViewSet, self).get_queryset() queryset = super(AssetViewSet, self).get_queryset()
idc_id = self.request.query_params.get('idc_id', '') idc_id = self.request.query_params.get('idc_id', '')
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', '') 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: if idc_id:
queryset = queryset.filter(idc__id=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: if asset_group_id:
queryset = queryset.filter(groups__id=asset_group_id) queryset = queryset.filter(groups__id=asset_group_id)
return queryset return queryset
class AssetGroupViewSet(viewsets.ModelViewSet): class AssetGroupViewSet(IDInFilterMixin, BulkModelViewSet):
""" API endpoint that allows AssetGroup to be viewed or edited.
some other comment
"""
queryset = AssetGroup.objects.all() queryset = AssetGroup.objects.all()
serializer_class = serializers.AssetGroupSerializer serializer_class = serializers.AssetGroupSerializer
permission_classes = (IsSuperUser,)
class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView): class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView):
@ -47,20 +54,41 @@ class AssetUpdateGroupApi(generics.RetrieveUpdateAPIView):
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class IDCViewSet(viewsets.ModelViewSet): ## 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,)
## 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.""" """API endpoint that allows IDC to be viewed or edited."""
queryset = IDC.objects.all() queryset = IDC.objects.all()
serializer_class = serializers.IDCSerializer serializer_class = serializers.IDCSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class AdminUserViewSet(viewsets.ModelViewSet): class AdminUserViewSet(IDInFilterMixin, BulkModelViewSet):
queryset = AdminUser.objects.all() queryset = AdminUser.objects.all()
serializer_class = serializers.AdminUserSerializer serializer_class = serializers.AdminUserSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class SystemUserViewSet(viewsets.ModelViewSet): class SystemUserViewSet(IDInFilterMixin, BulkModelViewSet):
queryset = SystemUser.objects.all() queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserSerializer serializer_class = serializers.SystemUserSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
@ -72,6 +100,18 @@ class SystemUserUpdateApi(generics.RetrieveUpdateAPIView):
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class SystemUserUpdateAssetsApi(generics.RetrieveUpdateAPIView):
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserUpdateAssetsSerializer
permission_classes = (IsSuperUser,)
class SystemUserUpdateAssetGroupApi(generics.RetrieveUpdateAPIView):
queryset = SystemUser.objects.all()
serializer_class = serializers.SystemUserUpdateAssetGroupSerializer
permission_classes = (IsSuperUser,)
# class IDCAssetsApi(generics.ListAPIView): # class IDCAssetsApi(generics.ListAPIView):
# model = IDC # model = IDC
# serializer_class = serializers.AssetSerializer # serializer_class = serializers.AssetSerializer
@ -93,7 +133,7 @@ class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
class SystemUserAuthInfoApi(generics.RetrieveAPIView): class SystemUserAuthInfoApi(generics.RetrieveAPIView):
queryset = SystemUser.objects.all() queryset = SystemUser.objects.all()
permission_classes = (IsSuperUserOrAppUser,) permission_classes = (IsAppUser,)
def retrieve(self, request, *args, **kwargs): def retrieve(self, request, *args, **kwargs):
system_user = self.get_object() system_user = self.get_object()
@ -107,3 +147,16 @@ class SystemUserAuthInfoApi(generics.RetrieveAPIView):
} }
return Response(data) return Response(data)
class TagViewSet(IDInFilterMixin, BulkModelViewSet):
queryset = Tag.objects.all()
serializer_class = serializers.TagSerializer
permission_classes = (IsSuperUser,)
## update the IDC, and add or delete the assets to the IDC
class TagUpdateAssetsApi(generics.RetrieveUpdateAPIView):
queryset = Tag.objects.all()
serializer_class = serializers.TagUpdateAssetsSerializer
permission_classes = (IsSuperUser,)

View File

@ -37,6 +37,14 @@ class AssetCreateForm(forms.ModelForm):
self.instance.tags.clear() self.instance.tags.clear()
self.instance.tags.add(*tuple(tags)) self.instance.tags.add(*tuple(tags))
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: class Meta:
model = Asset model = Asset
tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all()) tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all())
@ -293,10 +301,10 @@ class AssetTagForm(forms.ModelForm):
super(AssetTagForm, self).__init__(*args, **kwargs) super(AssetTagForm, self).__init__(*args, **kwargs)
def _save_m2m(self): def _save_m2m(self):
super(AssetTagForm, self)._save_m2m()
assets = self.cleaned_data['assets'] assets = self.cleaned_data['assets']
self.instance.asset_set.clear() self.instance.assets.clear()
self.instance.asset_set.add(*tuple(assets)) self.instance.assets.add(*tuple(assets))
super(AssetTagForm, self)._save_m2m()
class Meta: class Meta:
model = Tag model = Tag

View File

@ -12,5 +12,5 @@
from users.utils import AdminUserRequiredMixin from users.utils import AdminUserRequiredMixin
from users.permissions import IsSuperUserOrAppUser, IsSuperUser from users.permissions import IsAppUser, IsSuperUser
from users.models import User, UserGroup from users.models import User, UserGroup

View File

@ -68,7 +68,7 @@ class Asset(models.Model):
is_active = models.BooleanField(default=True, verbose_name=_('Is active')) is_active = models.BooleanField(default=True, verbose_name=_('Is active'))
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date added')) date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Date added'))
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment')) comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
tags = models.ManyToManyField('Tag', blank=True, verbose_name=_('Tags')) tags = models.ManyToManyField('Tag', related_name='assets', blank=True, verbose_name=_('Tags'))
def __unicode__(self): def __unicode__(self):
return '%(ip)s:%(port)s' % {'ip': self.ip, 'port': self.port} return '%(ip)s:%(port)s' % {'ip': self.ip, 'port': self.port}
@ -125,4 +125,4 @@ class Tag(models.Model):
__str__ = __unicode__ __str__ = __unicode__
class Meta: class Meta:
ordering = ['name'] db_table = 'tag'

View File

@ -15,8 +15,8 @@ def initial():
def generate_fake(): def generate_fake():
for cls in [IDC, SystemUser, AdminUser, AssetGroup, Asset, Tag]: for cls in [IDC, SystemUser, AdminUser, AssetGroup, Asset, Tag]:
if hasattr(cls, 'generake_fake'): if hasattr(cls, 'generate_fake'):
cls.generake_fake() cls.generate_fake()
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -1,17 +1,19 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework import viewsets, serializers,generics from rest_framework import viewsets, serializers,generics
from .models import AssetGroup, Asset, IDC, AdminUser, SystemUser from .models import AssetGroup, Asset, IDC, AdminUser, SystemUser, Tag
from common.mixins import IDInFilterMixin from common.mixins import IDInFilterMixin
from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin from rest_framework_bulk import BulkListSerializer, BulkSerializerMixin
class AssetGroupSerializer(serializers.ModelSerializer): class AssetGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer):
assets_amount = serializers.SerializerMethodField() assets_amount = serializers.SerializerMethodField()
# assets = serializers.PrimaryKeyRelatedField(many=True, read_only=True) assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta: class Meta:
model = AssetGroup model = AssetGroup
list_serializer_class = BulkListSerializer
fields = ['id', 'name', 'comment', 'assets_amount']
@staticmethod @staticmethod
def get_assets_amount(obj): def get_assets_amount(obj):
@ -34,7 +36,47 @@ class AssetUpdateSystemUserSerializer(serializers.ModelSerializer):
fields = ['id', 'system_users'] fields = ['id', 'system_users']
class AssetGroupUpdateSerializer(serializers.ModelSerializer):
"""update the asset group, and add or delete the asset to the group"""
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = AssetGroup
fields = ['id', 'assets']
class AssetGroupUpdateSystemUserSerializer(serializers.ModelSerializer):
system_users = serializers.PrimaryKeyRelatedField(many=True, queryset=SystemUser.objects.all())
class Meta:
model = AssetGroup
fields = ['id', 'system_users']
class IDCUpdateAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = IDC
fields = ['id', 'assets']
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 AdminUserSerializer(serializers.ModelSerializer): class AdminUserSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta: class Meta:
model = AdminUser model = AdminUser
@ -55,6 +97,22 @@ class SystemUserSerializer(serializers.ModelSerializer):
return fields return fields
class SystemUserUpdateAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = SystemUser
fields = ['id', 'assets']
class SystemUserUpdateAssetGroupSerializer(serializers.ModelSerializer):
asset_groups = serializers.PrimaryKeyRelatedField(many=True, queryset=AssetGroup.objects.all())
class Meta:
model = SystemUser
fields = ['id', 'asset_groups']
class SystemUserSimpleSerializer(serializers.ModelSerializer): class SystemUserSimpleSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = SystemUser model = SystemUser
@ -69,6 +127,7 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
class Meta(object): class Meta(object):
model = Asset model = Asset
list_serializer_class = BulkListSerializer list_serializer_class = BulkListSerializer
fields = ['__all__']
@staticmethod @staticmethod
def get_hardware(obj): def get_hardware(obj):
@ -84,7 +143,7 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
class AssetGrantedSerializer(serializers.ModelSerializer): class AssetGrantedSerializer(serializers.ModelSerializer):
system_users = SystemUserSimpleSerializer(many=True, read_only=True) system_users = SystemUserSerializer(many=True, read_only=True)
is_inherited = serializers.SerializerMethodField() is_inherited = serializers.SerializerMethodField()
system_users_join = serializers.SerializerMethodField() system_users_join = serializers.SerializerMethodField()
@ -105,8 +164,9 @@ class AssetGrantedSerializer(serializers.ModelSerializer):
return ', '.join([system_user.username for system_user in obj.system_users.all()]) return ', '.join([system_user.username for system_user in obj.system_users.all()])
class IDCSerializer(serializers.ModelSerializer): class IDCSerializer(BulkSerializerMixin, serializers.ModelSerializer):
assets_amount = serializers.SerializerMethodField() assets_amount = serializers.SerializerMethodField()
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta: class Meta:
model = IDC model = IDC
@ -119,3 +179,11 @@ class IDCSerializer(serializers.ModelSerializer):
fields = super(IDCSerializer, self).get_field_names(declared_fields, info) fields = super(IDCSerializer, self).get_field_names(declared_fields, info)
fields.append('assets_amount') fields.append('assets_amount')
return fields return fields
class TagUpdateAssetsSerializer(serializers.ModelSerializer):
assets = serializers.PrimaryKeyRelatedField(many=True, queryset=Asset.objects.all())
class Meta:
model = Tag
fields = ['id', 'assets']

View File

@ -6,7 +6,6 @@
{% block modal_body %} {% block modal_body %}
{% load bootstrap %} {% load bootstrap %}
<p class="text-success text-center">{% trans "Hint: only change the field you want to update." %}</p> <p class="text-success text-center">{% trans "Hint: only change the field you want to update." %}</p>
<div class="ydxbd" id="ydxbd" style="display: block;"> <div class="ydxbd" id="ydxbd" style="display: block;">
<div> <div>
<p id="tags_p"> <p id="tags_p">
@ -18,18 +17,22 @@
</div> </div>
<form method="post" class="form-horizontal" action="" id="fm_asset_bulk_update"> <form method="post" class="form-horizontal" action="" id="fm_asset_bulk_update">
<div class="form-group"> <div class="form-group">
<label class="control-label col-sm-2 col-lg-2 " for="id_role">{% trans "Role" %}</label> <label class="control-label col-sm-2 col-lg-2 " for="id_type">{% trans "System Type" %}</label>
<div class=" col-sm-9 col-lg-9 "> <div class=" col-sm-9 col-lg-9 ">
<select class=" select2 form-control" id="id_role" name="role"> <select class=" select2 form-control" id="id_type" name="type">
<option value="">---------</option> <option value="">---------</option>
<option value="Admin">{% trans "Admin" %}</option> <option value="Server">{% trans "Server" %}</option>
<option value="User">{% trans "User" %}</option> <option value="VM">{% trans "VM" %}</option>
<option value="Switch">{% trans "Switch" %}</option>
<option value="Storage">{% trans "Storage" %}</option>
<option value="Router">{% trans "Router" %}</option>
<option value="Firewall">{% trans "Firewall" %}</option>
</select> </select>
</div> </div>
</div> </div>
<div class="form-group">
<label for="groups" class="col-sm-2 control-label">{% trans 'Groups' %}</label> <div class="form-group">
<label for="groups" class="col-sm-2 control-label">{% trans 'Asset Groups' %}</label>
<div class="col-sm-9" id="select2-container"> <div class="col-sm-9" id="select2-container">
<select name="groups" id="select2_groups" data-placeholder="{% trans 'Select Group' %}" class="select2 form-control m-b" multiple> <select name="groups" id="select2_groups" data-placeholder="{% trans 'Select Group' %}" class="select2 form-control m-b" multiple>
{% for group in groups %} {% for group in groups %}
@ -38,6 +41,18 @@
</select> </select>
</div> </div>
</div> </div>
<div class="form-group">
<label for="users" class="col-sm-2 control-label">{% trans 'System Users' %}</label>
<div class="col-sm-9" id="select2-container">
<select name="system_users" id="select2_users" data-placeholder="{% trans 'Select System Users' %}" class="select2 form-control m-b" multiple>
{% for system_user in system_users %}
<option value="{{ system_user.id }}">{{ system_user.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-9 col-lg-9 col-sm-offset-2"> <div class="col-sm-9 col-lg-9 col-sm-offset-2">
<div class="checkbox checkbox-success"> <div class="checkbox checkbox-success">
@ -48,27 +63,16 @@
<div class="form-group"> <div class="form-group">
<label class="control-label col-sm-2 col-lg-2 " for="id_tags">标签集合</label> <label class="control-label col-sm-2 col-lg-2 " for="id_tags">标签集合</label>
<div class=" col-sm-9 col-lg-9 "> <div class=" col-sm-9 col-lg-9 ">
<select multiple="multiple" class="select2 form-control" data-placeholder="Select asset tags" id="tags" name="tags"> <select multiple="multiple" class="select2 form-control" data-placeholder="Select asset tags" id="tags" name="tags">
<option value="1">物理机</option> {% for tag in tags %}
<option value="2">虚拟机</option> <option value="{{ tag.id }}">{{ tag.name }}</option>
<option value="3">数据库备份</option> {% endfor %}
<option value="4">亦庄机房</option>
<option value="5">三年质保</option>
</select> </select>
<p class="help-block"> <p class="help-block">
最多5个标签单个标签最长8个汉字按回车确认 最多5个标签单个标签最长8个汉字按回车确认
</p> </p>
</div> </div>
</div> </div>

View File

@ -0,0 +1,42 @@
{% extends '_modal.html' %}
{% load i18n %}
{% block modal_id %}asset_group_bulk_update_modal{% endblock %}
{% block modal_class %}modal-lg{% endblock %}
{% block modal_title%}{% trans "Update Asset Group" %}{% endblock %}
{% block modal_body %}
{% load bootstrap %}
<p class="text-success text-center">{% trans "Hint: only change the field you want to update." %}</p>
<form method="post" class="form-horizontal" action="" id="fm_asset_group_bulk_update">
<div class="form-group">
<label for="assets" class="col-sm-2 control-label">{% trans 'Assets' %}</label>
<div class="col-sm-9" id="select2-container">
<select name="assets" id="select2_groups" data-placeholder="{% trans 'Select Asset' %}" class="select2 form-control m-b" multiple>
{% for asset in assets %}
<option value="{{ asset.id }}">{{ asset.ip }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<label for="system_users" class="col-sm-2 control-label">{% trans 'System Users' %}</label>
<div class="col-sm-9" id="select2-container">
<select name="system_users" id="select2_groups" data-placeholder="{% trans 'Select System Users' %}" class="select2 form-control m-b" multiple>
{% for system_user in system_users %}
<option value="{{ system_user.id }}">{{ system_user.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-9 col-lg-9 col-sm-offset-2">
<div class="checkbox checkbox-success">
<input type="checkbox" name="enable_otp" checked id="id_enable_otp"><label for="id_enable_otp">{% trans 'Enable-OTP' %}</label>
</div>
</div>
</div>
</form>
{% endblock %}
{% block modal_confirm_id %}btn_asset_group_bulk_update{% endblock %}

View File

@ -88,29 +88,30 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table table-hover"> <table class="table table-hover" id="system_user_assets_table">
<thead> <thead>
<tr> <tr>
<th>{% trans 'Hostname' %}</th> <th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th> <th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th> <th>{% trans 'Port' %}</th>
<th>{% trans 'Alive' %}</th> <th>{% trans 'Alive' %}</th>
<th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for asset in page_obj %} {# {% for asset in page_obj %}#}
<tr> {# <tr>#}
<td>{{ asset.hostname }}</td> {# <td>{{ asset.hostname }}</td>#}
<td>{{ asset.ip }}</td> {# <td>{{ asset.ip }}</td>#}
<td>{{ asset.port }}</td> {# <td>{{ asset.port }}</td>#}
<td>Alive</td> {# <td>Alive</td>#}
</tr> {# </tr>#}
{% endfor %} {# {% endfor %}#}
</tbody> </tbody>
</table> </table>
<div class="row"> {# <div class="row">#}
{% include '_pagination.html' %} {# {% include '_pagination.html' %}#}
</div> {# </div>#}
</div> </div>
</div> </div>
</div> </div>
@ -164,15 +165,15 @@
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for group in groups %} {% for asset in assets_remain %}
<option value="{{ group.id }}">{{ group.name }}</option> <option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-info btn-sm">{% trans 'Replace' %}</button> <button type="button" class="btn btn-info btn-sm btn-replace-asset-admin_user">{% trans 'Replace' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
@ -192,15 +193,15 @@
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select asset groups' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select asset groups' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for group in groups %} {% for asset_group in asset_groups %}
<option value="{{ group.id }}">{{ group.name }}</option> <option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-warning btn-sm">{% trans 'Replace' %}</button> <button type="button" class="btn btn-warning btn-sm btn-replace-asset_groups-admin_user">{% trans 'Replace' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
@ -219,25 +220,180 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
{# function switch_user_status(obj) {#} Array.prototype.remove = function(val) {
{# var status = $(obj).prop('checked');#} var index = this.indexOf(val);
{##} if (index > -1) {
{# $.ajax({#} this.splice(index, 1);
{# url: "{% url 'users:user-active-api' pk=user.id %}",#} }
{# type: "PUT",#} };
{# data: {#} Array.prototype.unique = function(){
{# 'is_active': status#} var res = [];
{# },#} var json = {};
{# success: function (data, status) {#} for(var i = 0; i < this.length; i++){
{# console.log(data)#} if(!json[this[i]]){
{# },#} res.push(this[i]);
{# error: function () {#} json[this[i]] = 1;
{# console.log('error')#} }
{# }#} }
{# })#} return res;
{# }#} };
function objectRemove(obj, name, url, data) {
function doRemove() {
var body = data;
var success = function() {
swal('Remove!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Remove"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
});
}
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 () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
jumpserver.asset_groups_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
delete jumpserver.asset_groups_selected[data.id]
});
var options = {
ele: $('#system_user_assets_table'),
buttons: [],
order: [],
columnDefs: [
{targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_remove" data-aid="99991937">{% trans "Remove" %}</a>'.replace('99991937', rowData.id);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}?admin_user_id={{ admin_user.id }}',
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "is_active" }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn-replace-asset-admin_user', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
jumpserver.asset_groups_selected = {};
var $data_table = $("#system_user_assets_table").DataTable();
var assets = [];
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
assets.unique();
var data = [];
var admin_user_id = {{ admin_user.id }};
var the_url = '{% url "api-assets:asset-list" %}';
for (var i=0; i<assets.length; i++) {
data.push({"id": assets[i], "admin_user": admin_user_id});
}
APIUpdateAttr({
url: the_url,
body: JSON.stringify(data),
method: 'PATCH'
});
$data_table.ajax.reload();
})
.on('click', '.btn-replace-asset_groups-admin_user', function () {
if (Object.keys(jumpserver.asset_groups_selected).length === 0) {
return false;
}
jumpserver.assets_selected = {};
var $data_table = $("#system_user_assets_table").DataTable();
var asset_groups = [];
var assets = [];
var data = [];
var the_url = '{% url "api-assets:asset-list" %}';
$.map(jumpserver.asset_groups_selected, function(value, index) {
asset_groups.push(parseInt(index));
});
$.ajax({
url: '{% url "api-assets:asset-group-list" %}?id__in=['+asset_groups.join(',')+']',
method: 'GET',
dataType: 'json',
success: function (result) {
for (var i=0; i<result.length; i++) {
for (var j=0; j<result[i]['assets'].length; j++) {
assets.push(result[i]['assets'][j])
}
}
for (var z=0; z<assets.length; z++) {
data.push({"id":assets[z], "admin_user":{{admin_user.id}} });
}
APIUpdateAttr({
url: the_url,
body: JSON.stringify(data),
method: 'PATCH'
});
$data_table.ajax.reload();
}
});
})
.on('click', '.btn_asset_remove', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:admin-user-detail' pk=admin_user.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var assets = [];
var delete_asset_id = $(this).data('aid');
$.ajax({
url: the_url,
method: 'GET',
dataType: 'json',
success: function (result) {
for (var i=0; i<result['assets'].length; i++) {
assets.push(result['assets'][i])
}
assets.remove(delete_asset_id);
var data = {"assets": assets};
objectRemove($this, name, the_url, data);
}
});
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -23,6 +23,18 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block content_bottom_left %}{% endblock %} {% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
@ -48,8 +60,72 @@ $(document).ready(function(){
ajax_url: '{% url "api-assets:admin-user-list" %}', ajax_url: '{% url "api-assets:admin-user-list" %}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () {return 'lost'} }, columns: [{data: function(){return ""}}, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () {return 'lost'} },
{data: "comment" }, {data: "id" }], {data: "comment" }, {data: "id" }],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn_admin_user_delete', function () {
var $this = $(this);
var $data_table = $("#admin_user_list_table").DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:admin-user-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#admin_user_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (plain_id_list.length == 0) {
return false;
}
var the_url = "{% url 'api-assets:admin-user-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected Admin Users !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Admin Users Deleted.' %}";
swal("{% trans 'Admin Users Delete' %}", msg, "success");
$('#admin_user_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Admin Users Deleting failed.' %}";
swal("{% trans 'Admin Users Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -200,7 +200,7 @@
<i class="fa fa-info-circle"></i> {% trans 'Asset groups' %} <i class="fa fa-info-circle"></i> {% trans 'Asset groups' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table group_edit"> <table class="table group_edit" id="add-asset2group">
<tbody> <tbody>
<form> <form>
<tr> <tr>
@ -236,7 +236,7 @@
<i class="fa fa-info-circle"></i> {% trans 'System users' %} <i class="fa fa-info-circle"></i> {% trans 'System users' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table group_edit"> <table class="table group_edit" id="add-asset2systemuser">
<tbody> <tbody>
<form> <form>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
@ -288,7 +288,7 @@ function updateAssetGroups(groups) {
$.map(jumpserver.groups_selected, function(group_name, index) { $.map(jumpserver.groups_selected, function(group_name, index) {
$('#opt_' + index).remove(); $('#opt_' + index).remove();
// change tr html of user groups. // change tr html of user groups.
$('.group_edit tbody').append( $('#add-asset2group tbody').append(
'<tr>' + '<tr>' +
'<td><b class="bdg_group" data-gid="' + index + '">' + group_name + '</b></td>' + '<td><b class="bdg_group" data-gid="' + index + '">' + group_name + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' + '<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' +
@ -316,7 +316,7 @@ function updateAssetSystem(system_users) {
$.map(jumpserver.groups_selected, function(name, index) { $.map(jumpserver.groups_selected, function(name, index) {
$('#opt_' + index).remove(); $('#opt_' + index).remove();
$('.group_edit tbody').append( $('#add-asset2systemuser tbody').append(
'<tr>' + '<tr>' +
'<td><b class="bdg_group" data-sid="' + index + '">' + name + '</b></td>' + '<td><b class="bdg_group" data-sid="' + index + '">' + name + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_system" type="button"><i class="fa fa-minus"></i></button></td>' + '<td><button class="btn btn-danger btn-xs pull-right btn_leave_system" type="button"><i class="fa fa-minus"></i></button></td>' +
@ -418,7 +418,6 @@ $(document).ready(function () {
var system_users = $('.bdg_group').map(function () { var system_users = $('.bdg_group').map(function () {
return $(this).data('sid'); return $(this).data('sid');
}).get(); }).get();
console.log(system_users);
updateAssetSystem(system_users) updateAssetSystem(system_users)
}) })

View File

@ -48,10 +48,28 @@
<th>{% trans 'Hostname' %}</th> <th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th> <th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th> <th>{% trans 'Port' %}</th>
<th>{% trans 'Type' %}</th>
<th>{% trans 'Alive' %}</th> <th>{% trans 'Alive' %}</th>
<th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{# {% for asset in assets %}#}
{# <tr id="bdg_asset" data-aid="{{ asset.id }}">#}
{# <td>{{ asset.hostname }}</td>#}
{# <td>{{ asset.ip }}</td>#}
{# <td>{{ asset.port }}</td>#}
{# {% if asset.is_active %}#}
{# <td><i class="fa fa-circle text-navy"></i></td>#}
{# {% else %}#}
{# <td><i class="fa fa-circle text-danger"></i></td>#}
{# {% endif %}#}
{# <td>#}
{# <a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="{{ asset.id }}">{% trans "Delete" %}</a>#}
{# <a class="btn btn-xs btn-info m-l-xs btn_asset_update" data-aid="{{ asset.id }}" href="{% url 'assets:asset-update' pk=asset.id %}">{% trans "Update" %}</a>#}
{# </td>#}
{# </tr>#}
{# {% endfor %}#}
</tbody> </tbody>
</table> </table>
</div> </div>
@ -70,14 +88,14 @@
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select assets' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select assets' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for asset in assets_remain %} {% for asset in assets_remain %}
<option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option> <option value="{{ asset.id }}" id="opt_{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-primary btn-sm">{% trans 'Add' %}</button> <button type="button" class="btn btn-primary btn-sm btn-asset-add-groups">{% trans 'Add' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
@ -91,29 +109,29 @@
<i class="fa fa-info-circle"></i> {% trans 'Associate system user' %} <i class="fa fa-info-circle"></i> {% trans 'Associate system user' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table"> <table class="table system-user-table">
<tbody> <tbody>
<form> <form>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select system user' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select system user' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for system_user in system_users_remain %} {% for system_user in system_users_remain %}
<option value="{{ system_user.id }}">{{ system_user.name }}</option> <option value="{{ system_user.id }}" id="opt_{{ system_user.id }}">{{ system_user.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-info btn-sm">{% trans 'Associate' %}</button> <button type="button" class="btn btn-info btn-sm btn-asset-add-groups-system-users">{% trans 'Associate' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
{% for system_user in system_users %} {% for system_user in system_users %}
<tr> <tr>
<td ><b>{{ group.name }}</b></td> <td ><b class="bdg_system_user" data-sid={{ system_user.id }}>{{ system_user.name }}</b></td>
<td> <td>
<button class="btn btn-danger btn-xs" type="button" style="float: right;"><i class="fa fa-minus"></i></button> <button class="btn btn-danger btn-xs pull-right btn_leave_asset_group" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
@ -133,52 +151,248 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
jumpserver.assets_selected = {};
jumpserver.system_users_selected = {};
function updateAssetsGroup(assets) {
var the_url = "{% url 'api-assets:asset-groups-update' pk=asset_group.id %}";
var body = {
assets: Object.assign([], assets)
};
var success = function(data) {
$('select2-selection__rendered').empty();
$('#groups_selected').val('');
$('#asset_list_table > tbody').empty();
$.map(jumpserver.assets_selected, function(asset_ip, index) {
var url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace(99991937, index);
asset = $.ajax({
url: url,
method: "GET",
dataType: "json",
success: function (data, textStatus) {
var add_tr = '<tr id="bdg_asset" data-aid="'+data.id+'">'+
'<td>'+data.hostname+'</td>'+
'<td>'+data.ip+'</td>'+
'<td>'+data.port+'</td>'+
'<td>status</td>'+
'<td>'+
'<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="'+data.id+'">{% trans "Delete" %}</a>'+
'<a class="btn btn-xs btn-info m-l-xs btn_asset_update" data-aid="'+data.id+'" href="'+'{% url "assets:asset-update" pk=99991937 %}'.replace(99991937, data.id)+'">{% trans "Update" %}</a>'+
'</td>'+
'</tr>';
(data.is_active == true) ? tr = add_tr.replace('<td>status</td>', '<td><i class="fa fa-circle text-navy"></i></td>'): tr = add_tr.replace('<td>status</td>', '<td><i class="fa fa-circle text-danger"></i></td>');
$('#asset_list_table > tbody').append(tr);
}
});
});
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
function objectDelete(obj, name, url, data) {
function doDelete() {
var body = data;
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
function updateAssetGroupSystemUsers(system_users) {
var the_url = "{% url 'api-assets:asset-groups-update-systemusers' pk=asset_group.id %}";
var body = {
system_users: Object.assign([], system_users)
};
var success = function(data) {
$('.select2-selection__rendered').empty();
$('#groups_selected').val('');
$.map(jumpserver.system_users_selected, function(system_user, index) {
$('#opt_' + index).remove();
$('.system-user-table tbody').append(
'<tr>' +
'<td><b class="bdg_group" data-sid="' + index + '">' + system_user + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn_leave_group" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>'
)
});
jumpserver.system_users_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
Array.prototype.unique = function(){
var res = [];
var json = {};
for(var i = 0; i < this.length; i++){
if(!json[this[i]]){
res.push(this[i]);
json[this[i]] = 1;
}
}
return res;
};
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
jumpserver.system_users_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
delete jumpserver.system_users_selected[data.id]
});
var options = { var options = {
ele: $('#asset_list_table'), ele: $('#asset_list_table'),
buttons: [], buttons: [],
order: [], order: [],
select: [],
columnDefs: [ columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) { {targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "perms:asset-permission-detail" pk=99991937 %}">' + cellData + '</a>'; var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id)); $(td).html(detail_btn.replace('99991937', rowData.id));
}}, }},
{targets: 2, createdCell: function (td, cellData, rowData) { {targets: 4, createdCell: function (td, cellData) {
var dataLength = cellData.length;
$(td).html(dataLength);
}},
{targets: 3, createdCell: function (td, cellData, rowData) {
var dataLength = cellData.length;
$(td).html(dataLength);
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var dataLength = cellData.length;
$(td).html(dataLength);
}},
{targets: 5, createdCell: function (td, cellData) {
if (!cellData) { if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>') $(td).html('<i class="fa fa-times text-danger"></i>')
} else { } else {
$(td).html('<i class="fa fa-check text-navy"></i>') $(td).html('<i class="fa fa-check text-navy"></i>')
} }
}}, }},
{targets: 6, createdCell: function (td, cellData, rowData) { {targets: 5, createdCell: function (td, cellData, rowData) {
var btn = '<button class="btn btn-danger btn-xs btn_del_permission disabled" id=99991937 type="button" style="float: right;"><i class="fa fa-minus"></i></button>'; var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
if (rowData.is_inherited) { var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Remove" %}</a>'.replace('99991937', rowData.id);
$(td).html(btn) $(td).html(update_btn + del_btn)
} else {
btn = btn.replace('99991937', cellData);
$(td).html(btn.replace('disabled', ''));
}
}} }}
], ],
ajax_url: '{% url "api-perms:asset-permission-list" %}?user={{ user.id }}', ajax_url: '{% url "api-assets:asset-list" %}?asset_group_id={{ asset_group.id }}',
columns: [{data: function(){return ""}}, {data: "name" }, {data: "assets" }, {data: "asset_groups"}, columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "system_users"}, {data: "is_active"}, {data: "id"}] {data: "type" }, {data: "is_active" }, {data: "id"}],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
}) })
.on('click', '.btn-asset-add-groups', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
jumpserver.system_users_selected = {};
var $data_table = $("#asset_list_table").DataTable();
var assets = [];
$.ajax({
url: '{% url "api-assets:asset-list" %}?asset_group_id={{ asset_group.id }}',
method: 'GET',
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
assets.unique();
var the_url = "{% url 'api-assets:asset-groups-update' pk=asset_group.id %}";
var body = {"assets": assets};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PATCH'
});
{# TODO: reflash the table and reset the jumpserver variables #}
{# window.location.href='{% url "assets:asset-group-detail" pk=asset_group.id %}';#}
}
});
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:asset-groups-update' pk=asset_group.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var assets = [];
$('#asset_list_table > tbody > tr').map(function () {
assets.push(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
});
var delete_asset_id = $(this).data('aid');
assets.remove(delete_asset_id);
var data = {"assets": assets};
objectDelete($this, name, the_url, data);
})
.on('click', '.btn-asset-add-groups-system-users', function () {
if (Object.keys(jumpserver.system_users_selected).length === 0) {
return false;
}
jumpserver.assets_selected = {};
var system_users = $('.bdg_system_user').map(function() {
return $(this).data('sid');
}).get();
$.map(jumpserver.system_users_selected, function(value, index) {
system_users.push(parseInt(index));
$('#opt_' + index).remove();
});
system_users.unique();
updateAssetGroupSystemUsers(system_users);
})
.on('click', '.btn_leave_asset_group', function () {
var $this = $(this);
var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_system_user');
var sid = $badge.data('sid');
var name = $badge.html() || $badge.text();
$('system-user-table').append(
'<option value="' + sid + '" id="opt_' + sid + '">' + name + '</option>'
);
$tr.remove();
var system_users = $('.bdg_system_user').map(function () {
return $(this).data('sid');
}).get();
updateAssetGroupSystemUsers(system_users)
})
</script> </script>
{% endblock %} {% endblock %}

View File

@ -21,6 +21,20 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% include 'assets/_asset_group_bulk_update_modal.html' %}
{% endblock %} {% endblock %}
{% block content_bottom_left %}{% endblock %} {% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
@ -43,16 +57,124 @@ $(document).ready(function(){
$(td).html(update_btn + del_btn) $(td).html(update_btn + del_btn)
}}], }}],
ajax_url: '{% url "api-assets:asset-group-list" %}', ajax_url: '{% url "api-assets:asset-group-list" %}',
columns: [{data: "id"}, {data: "name" }, {data: "assets_amount" }, {data: "comment" }, {data: "id"}] columns: [{data: "id"}, {data: "name" }, {data: "assets_amount" }, {data: "comment" }, {data: "id"}],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
}) })
.on('click', '.btn_asset_group_delete', function () { .on('click', '.btn_asset_group_delete', function () {
var $this = $(this); var $this = $(this);
var $data_table = $('#asset_groups_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html(); var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid'); var uid = $this.data('uid');
var the_url = '{% url "api-assets:asset-group-detail" pk=99991937 %}'.replace('99991937', uid); var the_url = '{% url "api-assets:asset-group-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url); objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#asset_groups_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
var the_url = '{% url "api-assets:asset-group-list" %}';
console.log(plain_id_list);
console.log(the_url);
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected groups !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Group Deleted.' %}";
swal("{% trans 'Group Delete' %}", msg, "success");
$('#asset_groups_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Group Deleting failed.' %}";
swal("{% trans 'Group Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
$('#asset_group_bulk_update_modal').modal('show');
}
switch(action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
})
.on('click', '#btn_asset_group_bulk_update', function () {
var json_data = $("#fm_asset_group_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.assets != undefined) {
body.assets = json_data.assets;
}
if (typeof body.assets === 'string') {
body.assets = [parseInt(body.assets)]
} else if(typeof body.assets === 'array') {
var new_assets = body.assets.map(Number);
body.assets = new_assets;
}
if (json_data.system_users != undefined) {
body.system_users = json_data.system_users;
}
if (typeof body.system_users === 'string') {
body.system_users = [parseInt(body.system_users)];
} else if (typeof body.system_users === 'array') {
var new_system_users = body.system_users.map(Number);
body.system_users = new_system_users;
}
var post_list = [];
var $data_table = $('#asset_groups_list_table').DataTable()
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
});
if (post_list === []) {
return false
}
var the_url = '{% url "api-assets:asset-group-list" %}';
var success = function() {
var msg = "{% trans 'The selected asset groups has been updated successfully.' %}";
swal("{% trans 'AssetGroup Updated' %}", msg, "success");
$('#asset_groups_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
{# console.log(JSON.stringify(post_list));#}
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});
$('#asset_group_bulk_update_modal').modal('hide');
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -72,6 +72,7 @@
<option value="delete">{% trans 'Delete selected' %}</option> <option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option> <option value="update">{% trans 'Update selected' %}</option>
<option value="deactive">{% trans 'Deactive selected' %}</option> <option value="deactive">{% trans 'Deactive selected' %}</option>
<option value="active">{% trans 'Active' %}</option>
</select> </select>
<div class="input-group-btn pull-left" style="padding-left: 5px;"> <div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary"> <button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
@ -81,6 +82,7 @@
</div> </div>
</div> </div>
{% include 'assets/_asset_import_modal.html' %} {% include 'assets/_asset_import_modal.html' %}
{% include 'assets/_asset_bulk_update_modal.html' %}
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
@ -129,7 +131,6 @@
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData); var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData); var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn) $(td).html(update_btn + del_btn)
}} }}
], ],
ajax_url: '{% url "api-assets:asset-list" %}', ajax_url: '{% url "api-assets:asset-list" %}',
@ -139,13 +140,13 @@
op_html: $('#actions').html() op_html: $('#actions').html()
}; };
var table = jumpserver.initDataTable(options); var table = jumpserver.initDataTable(options);
$('.btn_export').click(function () { $('.btn_export').click(function () {
var assets = []; var assets = [];
var rows = table.rows('.selected').data(); var rows = table.rows('.selected').data();
$.each(rows, function (index, obj) { $.each(rows, function (index, obj) {
assets.push(obj.id) assets.push(obj.id)
}); });
console.log(assets);
$.ajax({ $.ajax({
url: "{% url "assets:asset-export" %}", url: "{% url "assets:asset-export" %}",
method: 'POST', method: 'POST',
@ -159,7 +160,6 @@
} }
}) })
}); });
$('#btn_asset_import').click(function() { $('#btn_asset_import').click(function() {
var $form = $('#fm_asset_import'); var $form = $('#fm_asset_import');
$form.find('.help-block').remove(); $form.find('.help-block').remove();
@ -179,15 +179,150 @@
} }
$form.ajaxSubmit({success: success}); $form.ajaxSubmit({success: success});
}) })
}) })
.on('click', '.btn_asset_delete', function () { .on('click', '.btn_asset_delete', function () {
var $this = $(this); var $this = $(this);
var $data_table = $("#asset_list_table").DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html(); var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid'); var uid = $this.data('uid');
var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid); var the_url = '{% url "api-assets:asset-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url); 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_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:asset-list' %}";
function doDeactive() {
var body = $.each(id_list, function(index, asset_object) {
asset_object['is_active'] = false;
});
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
$data_table.ajax.reload();
jumpserver.checked = false;
}
function doActive() {
var body = $.each(id_list, function(index, asset_object) {
asset_object['is_active'] = true;
});
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(body)});
$data_table.ajax.reload();
jumpserver.checked = false;
}
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected assets !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Asset Deleted.' %}";
swal("{% trans 'Asset Delete' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Asset Deleting failed.' %}";
swal("{% trans 'Asset Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
$('#asset_bulk_update_modal').modal('show');
}
switch(action) {
case 'deactive':
doDeactive();
break;
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
case 'active':
doActive();
break;
default:
break;
}
})
.on('click', '#btn_asset_bulk_update', function () {
var json_data = $("#fm_asset_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.groups != undefined) {
body.groups = json_data.groups;
}
if (typeof body.groups === 'string') {
body.groups = [parseInt(body.groups)]
} else if(typeof body.groups === 'array') {
var new_groups = body.groups.map(Number);
body.groups = new_groups;
}
if (json_data.system_users != undefined) {
body.system_users = json_data.system_users;
}
if (typeof body.system_users === 'string') {
body.system_users = [parseInt(body.system_users)]
} else if(typeof body.system_users === 'array') {
var new_users = body.system_users.map(Number);
body.system_users = new_users;
}
if (json_data.tags != undefined) {
body.tags = json_data.tags;
}
if (typeof body.tags == 'string') {
body.tags = [parseInt(body.tags)];
} else if (typeof body.tags === 'array') {
var new_tags = body.tags.map(Number);
body.tags = new_tags;
}
var $data_table = $('#asset_list_table').DataTable();
var post_list = [];
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
});
if (post_list === []) {
return false
}
var the_url = "{% url 'api-assets:asset-list' %}";
var success = function() {
var msg = "{% trans 'The selected assets has been updated successfully.' %}";
swal("{% trans 'Asset Updated' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
console.log(JSON.stringify(post_list));
console.log(the_url);
{# APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});#}
$('#asset_bulk_update_modal').modal('hide');
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -77,80 +77,27 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table table-hover"> <table class="table table-striped table-bordered table-hover " id="tag_assets_table" >
<thead> <thead>
<tr> <tr>
<th>{% trans 'Hostname' %}</th> <th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th> <th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th> <th>{% trans 'Port' %}</th>
<th>{% trans 'Alive' %}</th> <th>{% trans 'Type' %}</th>
<th>{% trans 'Valid' %}</th>
<th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for asset in page_obj %}
<tr>
<td>{{ asset.hostname }}</td>
<td>{{ asset.ip }}</td>
<td>{{ asset.port }}</td>
<td>Alive</td>
</tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
<div class="row">
{% include '_pagination.html' %}
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0"> <div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary"> <div class="panel panel-primary">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Associate system user' %} <i class="fa fa-info-circle"></i> {% trans 'Add asset to this tag' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<tr class="no-borders-tr">
<td width="50%">{% trans 'repush system user' %}:</td>
<td>
<span style="float: right">
<button class="btn btn-danger btn-xs" type="button"><i class="fa fa-refresh"></i></button>
</span>
</td>
</tr>
<form>
<tr class="no-borders-tr">
<td colspan="2">
<select data-placeholder="{% trans 'Select system user' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for group in groups %}
<option value="{{ group.id }}">{{ group.name }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr class="no-borders-tr">
<td colspan="2">
<button type="button" class="btn btn-primary btn-sm">{% trans 'Associate' %}</button>
</td>
</tr>
</form>
{% for group in user.groups.all %}
<tr>
<td ><b>{{ group.name }}</b></td>
<td>
<button class="btn btn-danger btn-xs" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Add asset to this group' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table"> <table class="table">
@ -158,27 +105,19 @@
<form> <form>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select asset user' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for group in groups %} {% for asset in assets_remain %}
<option value="{{ group.id }}">{{ group.name }}</option> <option value="{{ asset.id }}">{{ asset.ip }}:{{ asset.port }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-info btn-sm">{% trans 'Add' %}</button> <button type="button" class="btn btn-info btn-sm btn-tag-asset-add">{% trans 'Add' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
{% for group in user.groups.all %}
<tr>
<td ><b>{{ group.name }}</b></td>
<td>
<button class="btn btn-danger btn-xs" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
</td>
</tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
@ -195,25 +134,146 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
{# function switch_user_status(obj) {#} jumpserver.assets_selected = {};
{# var status = $(obj).prop('checked');#}
{##} function updateTagAssets(assets) {
{# $.ajax({#} var the_url = "{% url 'api-assets:tag-update-assets' pk=tag.id %}";
{# url: "{% url 'users:user-active-api' pk=user.id %}",#} var body = {
{# type: "PUT",#} assets: Object.assign([], assets)
{# data: {#} };
{# 'is_active': status#} var $data_table = $("#tag_assets_table").DataTable();
{# },#} var success = function(data) {
{# success: function (data, status) {#} $('.select2-selection__rendered').empty();
{# console.log(data)#} $.map(jumpserver.assets_selected, function(asset_ip, index) {
{# },#} $('#opt_' + index).remove();
{# error: function () {#} $data_table.ajax.reload();
{# console.log('error')#} });
{# }#} jumpserver.groups_selected = {};
{# })#} };
{# }#} APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PUT',
success: success
});
}
function deleteTagAssets(obj, name, url, data) {
function doDelete() {
var body = data;
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
});
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
}) })
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
});
var options = {
ele: $('#tag_assets_table'),
buttons: [],
order: [],
columnDefs: [
{targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 4, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 5, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Delete" %}</a>'.replace('99991937', rowData.id);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}?tag_id={{ tag.id }}',
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "type" }, {data: "is_active" }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn-tag-asset-add', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
var assets=[];
var $data_table = $("#tag_assets_table").DataTable();
$.ajax({
url: '{% url "api-assets:asset-list" %}',
method: 'GET',
data: {"tag_id": {{ tag.id }}},
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
updateTagAssets(assets);
$data_table.ajax().reload();
}
})
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:tag-update-assets' pk=tag.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var assets = [];
$('#tag_assets_table > tbody > tr').map(function () {
assets.push(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
});
var delete_asset_id = $(this).data('aid');
assets.remove(delete_asset_id);
var data = {"assets": assets};
deleteTagAssets($this, name, the_url, data);
});
</script> </script>
{% endblock %} {% endblock %}

View File

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

View File

@ -7,6 +7,9 @@
{% block custom_head_css_js %} {% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet"> <link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script> <script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
<style type="text/css">
</style>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="wrapper wrapper-content animated fadeInRight"> <div class="wrapper wrapper-content animated fadeInRight">
@ -42,6 +45,7 @@
</a> </a>
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table table-striped table-bordered table-hover " id="idc_assets_table" > <table class="table table-striped table-bordered table-hover " id="idc_assets_table" >
<thead> <thead>
@ -59,13 +63,27 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-warning">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0"> <div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary"> <div class="panel panel-primary">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Attach to assets ' %} <i class="fa fa-info-circle"></i> {% trans 'Attach assets to IDC ' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table"> <table class="table">
@ -75,14 +93,14 @@
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select asset' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for asset in assets_remain %} {% for asset in assets_remain %}
<option value="{{ asset.id }}">{{ asset.ip}}:{{ asset.port }}</option> <option value="{{ asset.id }}" id="opt_{{ asset.id }}">{{ asset.ip}}:{{ asset.port }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-primary btn-sm">{% trans 'Attach' %}</button> <button type="button" class="btn btn-primary btn-sm btn-asset-attach">{% trans 'Attach Assets' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
@ -96,19 +114,77 @@
</div> </div>
</div> </div>
</div> </div>
{% include 'assets/_asset_bulk_update_modal.html' %}
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script src="{% static 'js/jquery.form.min.js' %}"></script>
<script> <script>
jumpserver.assets_selected = {};
Array.prototype.remove = function(val) {
var index = this.indexOf(val);
if (index > -1) {
this.splice(index, 1);
}
};
function updateIDCAssets(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) {
$('.select2-selection__rendered').empty();
$.map(jumpserver.assets_selected, function(asset_ip, index) {
$('#opt_' + index).remove();
$data_table.ajax.reload();
});
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 () { $(document).ready(function () {
$('.select2').select2(); $('.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 = { var options = {
ele: $('#idc_assets_table'), ele: $('#idc_assets_table'),
buttons: [], buttons: [],
order: [], order: [],
columnDefs: [ columnDefs: [
{targets: 1, createdCell: function (td, cellData, rowData) { {targets: 1, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}">' + cellData + '</a>'; var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id)); $(td).html(detail_btn.replace('99991937', rowData.id));
}}, }},
{targets: 5, createdCell: function (td, cellData) { {targets: 5, createdCell: function (td, cellData) {
@ -120,9 +196,173 @@
}}], }}],
ajax_url: '{% url "api-assets:asset-list" %}?idc_id={{ idc.id }}', ajax_url: '{% url "api-assets:asset-list" %}?idc_id={{ idc.id }}',
columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" }, columns: [{data: function(){return ""}}, {data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "type" }, {data: "is_active" }] {data: "type" }, {data: "is_active" }],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn-asset-attach', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
var assets=[];
var $data_table = $("#idc_assets_table").DataTable();
$.ajax({
url: '{% url "api-assets:asset-list" %}',
method: 'GET',
data: {"idc_id": {{ idc.id }}},
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
}); });
updateIDCAssets(assets);
}
});
})
.on('click', '#btn_bulk_update', function () {
var action = $("#slct_bulk_update").val();
var $data_table = $("#idc_assets_table").DataTable();
var id_list = [];
var plain_id_list = [];
var assets = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
$.ajax({
url: '{% url "api-assets:asset-list" %}',
data: {"idc_id": {{ idc.id }}},
dataType: 'json',
method: 'GET',
success: function (result) {
for (var i in result) {
if (!isNaN(result[i]['id'])) {
assets.push(result[i]['id']);
}
}
for (var j in plain_id_list) {
assets.remove(plain_id_list[j])
}
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected assets !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'Asset Deleted.' %}";
swal("{% trans 'Asset Delete' %}", msg, "success");
$('#idc_assets_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'Asset Deleting failed.' %}";
swal("{% trans 'Asset Delete' %}", msg, "error");
};
var url_delete = "{% url 'api-assets:idc-update-assets' pk=idc.id %}";
var body = {
assets: Object.assign([], assets)
};
APIUpdateAttr({url: url_delete, body: JSON.stringify(body), method: 'PUT', success: success, error: fail});
jumpserver.checked = false;
});
}
function doUpdate() {
$('#asset_bulk_update_modal').modal('show');
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
}
});
})
.on('click', '#btn_asset_bulk_update', function () {
var json_data = $("#fm_asset_bulk_update").serializeObject();
var body = {};
body.enable_otp = (json_data.enable_otp === 'on')? true: false;
if (json_data.type != '') {
body.type = json_data.type;
}
if (json_data.groups != undefined) {
body.groups = json_data.groups;
}
if (typeof body.groups === 'string') {
body.groups = [parseInt(body.groups)]
} else if(typeof body.groups === 'array') {
var new_groups = body.groups.map(Number);
body.groups = new_groups;
}
if (json_data.users != undefined) {
body.users = json_data.users;
}
if (typeof body.users === 'string') {
body.users = [parseInt(body.users)]
} else if(typeof body.users === 'array') {
var new_users = body.users.map(Number);
body.users = new_users;
}
if (json_data.tags != undefined) {
body.tags = json_data.tags;
}
if (typeof body.tags == 'string') {
body.tags = [parseInt(body.tags)];
} else if (typeof body.tags === 'array') {
var new_tags = body.tags.map(Number);
body.tags = new_tags;
}
var $data_table = $('#asset_list_table').DataTable();
var post_list = [];
$data_table.rows({selected: true}).every(function(){
var content = Object.assign({id: this.data().id}, body);
post_list.push(content);
});
if (post_list === []) {
return false
}
var the_url = "{% url 'api-assets:asset-list' %}";
var success = function() {
var msg = "{% trans 'The selected assets has been updated successfully.' %}";
swal("{% trans 'Asset Updated' %}", msg, "success");
$('#asset_list_table').DataTable().ajax.reload();
jumpserver.checked = false;
};
APIUpdateAttr({url: the_url, method: 'PATCH', body: JSON.stringify(post_list), success: success});
$('#asset_bulk_update_modal').modal('hide');
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -27,7 +27,7 @@
<a class="btn btn-outline btn-default" href="{% url 'assets:idc-update' pk=idc.id %}"><i class="fa fa-edit"></i>Update</a> <a class="btn btn-outline btn-default" href="{% url 'assets:idc-update' pk=idc.id %}"><i class="fa fa-edit"></i>Update</a>
</li> </li>
<li class="pull-right"> <li class="pull-right">
<a class="btn btn-outline btn-danger" href="{% url 'assets:idc-delete' pk=idc.id %}"> <a class="btn btn-outline btn-danger btn-delete-idc">
<i class="fa fa-edit"></i>Delete <i class="fa fa-edit"></i>Delete
</a> </a>
</li> </li>
@ -53,9 +53,9 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table"> <table class="table idc-details">
<tbody> <tbody>
<tr class="no-borders-tr"> <tr class="no-borders-tr" data-name="{{ idc.name }}">
<td>{% trans 'Name' %}:</td> <td>{% trans 'Name' %}:</td>
<td><b>{{ idc.name }}</b></td> <td><b>{{ idc.name }}</b></td>
</tr> </tr>
@ -114,25 +114,46 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
{# function switch_user_status(obj) {#} function idcDelete(name, url) {
{# var status = $(obj).prop('checked');#} function doDelete() {
{##} var body = {};
{# $.ajax({#} var success = function() {
{# url: "{% url 'users:user-active-api' pk=user.id %}",#} swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
{# type: "PUT",#} window.location.href="{% url 'assets:idc-list' %}";
{# data: {#} };
{# 'is_active': status#} var fail = function() {
{# },#} swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
{# success: function (data, status) {#} };
{# console.log(data)#} APIUpdateAttr({
{# },#} url: url,
{# error: function () {#} body: JSON.stringify(body),
{# console.log('error')#} method: 'DELETE',
{# }#} success: success,
{# })#} error: fail
{# }#} });
}
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 () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2();
})
.on('click', '.btn-delete-idc', function () {
var name = $('.idc-details > tbody > tr').attr("data-name");
var id = {{ idc.id }};
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace(99991937, id);
idcDelete(name, the_url);
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,5 +1,9 @@
{% extends '_base_list.html' %} {% extends '_base_list.html' %}
{% load i18n static %} {% load i18n static %}
{% block custom_head_css_js %}
<link href="{% static 'css/plugins/select2/select2.min.css' %}" rel="stylesheet">
<script src="{% static 'js/plugins/select2/select2.full.min.js' %}"></script>
{% endblock %}
{% block table_search %}{% endblock %} {% block table_search %}{% endblock %}
{% block table_container %} {% block table_container %}
<div class="uc pull-left m-l-5 m-r-5"> <div class="uc pull-left m-l-5 m-r-5">
@ -22,6 +26,18 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-warning">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block content_bottom_left %}{% endblock %} {% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
@ -34,20 +50,10 @@ $(document).ready(function(){
var detail_btn = '<a href="{% url "assets:idc-detail" pk=99991937 %}">' + cellData + '</a>'; var detail_btn = '<a href="{% url "assets:idc-detail" pk=99991937 %}">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id)); $(td).html(detail_btn.replace('99991937', rowData.id));
}}, }},
{# {targets: 4, createdCell: function (td, cellData) {#}
{# var innerHtml = cellData.length > 8 ? cellData.substring(0, 8) + '...': cellData;#}
{# $(td).html('<a href="javascript:void(0);" data-toggle="tooltip" title="' + cellData + '">' + innerHtml + '</a>');#}
{# }},#}
{# {targets: 6, createdCell: function (td, cellData) {#}
{# if (!cellData) {#}
{# $(td).html('<i class="fa fa-times text-danger"></i>')#}
{# } else {#}
{# $(td).html('<i class="fa fa-check text-navy"></i>')#}
{# }#}
{# }},#}
{targets: 6, createdCell: function (td, cellData, rowData) { {targets: 6, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:idc-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData); var update_btn = '<a href="{% url "assets:idc-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', cellData);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_user_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData); var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_idc_delete" data-uid="99991937">{% trans "Delete" %}</a>'.replace('99991937', cellData);
$(td).html(update_btn + del_btn) $(td).html(update_btn + del_btn)
}}], }}],
ajax_url: '{% url "api-assets:idc-list" %}', ajax_url: '{% url "api-assets:idc-list" %}',
@ -56,6 +62,64 @@ $(document).ready(function(){
op_html: $('#actions').html() op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn_idc_delete', function () {
var $this = $(this);
var $data_table = $('#idc_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:idc-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
{# TODO: reload the tale #}
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#idc_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
});
if (id_list === []) {
return false;
}
var the_url = "{% url 'api-assets:idc-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected idc !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'IDC Deleted.' %}";
swal("{% trans 'IDC Delete' %}", msg, "success");
$('#idc_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'IDC Deleting failed.' %}";
swal("{% trans 'IDC Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
switch (action) {
case 'delete':
doDelete();
break;
default:
break;
}
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -43,35 +43,35 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<table class="table table-hover"> <table class="table table-hover" id="system_user_list">
<thead> <thead>
<tr> <tr>
<th>{% trans 'Hostname' %}</th> <th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th> <th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th> <th>{% trans 'Port' %}</th>
<th>{% trans 'Reachable' %}</th> <th>{% trans 'Reachable' %}</th>
<th></th> <th>{% trans 'Action' %}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for asset in page_obj %} {# {% for asset in page_obj %}#}
<tr> {# <tr>#}
<td>{{ asset.hostname }}</td> {# <td>{{ asset.hostname }}</td>#}
<td>{{ asset.ip }}</td> {# <td>{{ asset.ip }}</td>#}
<td>{{ asset.port }}</td> {# <td>{{ asset.port }}</td>#}
<td> {# <td>#}
<i class="fa fa-check text-navy"></i> {# <i class="fa fa-check text-navy"></i>#}
</td> {# </td>#}
<td> {# <td>#}
<button class="btn btn-danger pull-right btn-xs {% if asset.is_inherit_from_asset_groups %} disabled {% endif %}" type="button"><i class="fa fa-minus"></i></button> {# <button class="btn btn-danger pull-right btn-xs {% if asset.is_inherit_from_asset_groups %} disabled {% endif %}" type="button"><i class="fa fa-minus"></i></button>#}
</td> {# </td>#}
</tr> {# </tr>#}
{% endfor %} {# {% endfor %}#}
</tbody> </tbody>
</table> </table>
<div class="row"> {# <div class="row">#}
{% include '_pagination.html' %} {# {% include '_pagination.html' %}#}
</div> {# </div>#}
</div> </div>
</div> </div>
</div> </div>
@ -95,7 +95,7 @@
</tr> </tr>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<button type="button" class="btn btn-primary btn-sm">{% trans 'Attach' %}</button> <button type="button" class="btn btn-primary btn-sm btn-add-asset2system-user">{% trans 'Attach Asset' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
@ -123,16 +123,16 @@
</tr> </tr>
<tr> <tr>
<td colspan="2" class="no-borders"> <td colspan="2" class="no-borders">
<button type="button" class="btn btn-info btn-sm" id="btn_add_user_group">{% trans 'Attach' %}</button> <button type="button" class="btn btn-info btn-sm" id="btn_add_user_group">{% trans 'Attach AssetGroup' %}</button>
</td> </td>
</tr> </tr>
</form> </form>
{% for asset_group in asset_groups %} {% for asset_group in asset_groups %}
<tr> <tr>
<td ><b data-gid={{ asset_group.id }}>{{ asset_group.name }}</b></td> <td ><b class="bdg_asset_groups" data-gid={{ asset_group.id }}>{{ asset_group.name }}</b></td>
<td> <td>
<button class="btn btn-danger pull-right btn-xs" type="button"><i class="fa fa-minus"></i></button> <button class="btn btn-danger pull-right btn-xs btn-leave-system_user" type="button"><i class="fa fa-minus"></i></button>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
@ -151,25 +151,223 @@
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
{# function switch_user_status(obj) {#} jumpserver.assets_selected = {};
{# var status = $(obj).prop('checked');#} jumpserver.asset_groups_selected = {};
{##} Array.prototype.remove = function(val) {
{# $.ajax({#} var index = this.indexOf(val);
{# url: "{% url 'users:user-active-api' pk=user.id %}",#} if (index > -1) {
{# type: "PUT",#} this.splice(index, 1);
{# data: {#} }
{# 'is_active': status#} };
{# },#} Array.prototype.unique = function(){
{# success: function (data, status) {#} var res = [];
{# console.log(data)#} var json = {};
{# },#} for(var i = 0; i < this.length; i++){
{# error: function () {#} if(!json[this[i]]){
{# console.log('error')#} res.push(this[i]);
{# }#} json[this[i]] = 1;
{# })#} }
{# }#} }
$(document).ready(function () { return res;
$('.select2').select2(); };
function objectDelete(obj, name, url, data) {
function doDelete() {
var body = data;
var success = function() {
swal('Deleted!', "[ "+name+"]"+" has been deleted ", "success");
$(obj).parent().parent().remove();
};
var fail = function() {
swal("Failed", "Delete"+"[ "+name+" ]"+"failed", "error");
};
APIUpdateAttr({
url: url,
body: JSON.stringify(body),
method: 'PATCH',
success: success,
error: fail
}); });
}
swal({
title: 'Are you sure delete ?',
text: " [" + name + "] ",
type: "warning",
showCancelButton: true,
cancelButtonText: 'Cancel',
confirmButtonColor: "#DD6B55",
confirmButtonText: 'Confirm',
closeOnConfirm: false
}, function () {
doDelete()
});
}
function updateSystemUserAssetGroup(asset_groups) {
var the_url = "{% url 'api-assets:systemuser-update-assetgroups' pk=system_user.id %}";
var body = {
asset_groups: Object.assign([], asset_groups)
};
var success = function(data) {
$('.select2-selection__rendered').empty();
$('#groups_selected').val('');
$.map(jumpserver.asset_groups_selected, function(asset_groups, index) {
$('#opt_' + index).remove();
$('.system-user-table tbody').append(
'<tr>' +
'<td><b class="bdg_asset_groups" data-sid="' + index + '">' + asset_groups + '</b></td>' +
'<td><button class="btn btn-danger btn-xs pull-right btn-leave-system_user" type="button"><i class="fa fa-minus"></i></button></td>' +
'</tr>'
)
});
jumpserver.assets_selected = {};
};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
success: success
});
}
$(document).ready(function () {
$('.select2').select2()
.on("select2:select", function (evt) {
var data = evt.params.data;
jumpserver.assets_selected[data.id] = data.text;
jumpserver.asset_groups_selected[data.id] = data.text;
})
.on('select2:unselect', function(evt) {
var data = evt.params.data;
delete jumpserver.assets_selected[data.id];
delete jumpserver.asset_groups_selected[data.id];
});
var options = {
ele: $('#system_user_list'),
buttons: [],
order: [],
columnDefs: [
{targets: 0, createdCell: function (td, cellData, rowData) {
var detail_btn = '<a href="{% url "assets:asset-detail" pk=99991937 %}" data-aid="'+rowData.id+'">' + cellData + '</a>';
$(td).html(detail_btn.replace('99991937', rowData.id));
}},
{targets: 3, createdCell: function (td, cellData) {
if (!cellData) {
$(td).html('<i class="fa fa-times text-danger"></i>')
} else {
$(td).html('<i class="fa fa-check text-navy"></i>')
}
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var update_btn = '<a href="{% url "assets:asset-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'.replace('99991937', rowData.id);
var del_btn = '<a class="btn btn-xs btn-danger m-l-xs btn_asset_delete" data-aid="99991937">{% trans "Delete" %}</a>'.replace('99991937', rowData.id);
$(td).html(update_btn + del_btn)
}}
],
ajax_url: '{% url "api-assets:asset-list" %}?system_user_id={{ system_user.id }}',
columns: [{data: "hostname" }, {data: "ip" }, {data: "port" }, {data: function () { return ""; } }, {data: "id"}],
op_html: $('#actions').html()
};
jumpserver.initDataTable(options);
})
.on('click', '.btn-add-asset2system-user', function () {
if (Object.keys(jumpserver.assets_selected).length === 0) {
return false;
}
var $data_table = $("#system_user_list").DataTable();
var assets = [];
$.ajax({
url: '{% url "api-assets:asset-list" %}?system_user_id={{ system_user.id }}',
method: 'GET',
dataType: 'json',
success: function (result) {
for(var i in result){
if (!isNaN(parseInt(result[i]['id']))) {
assets.push(parseInt(result[i]['id']))
}
}
$.map(jumpserver.assets_selected, function(value, index) {
assets.push(parseInt(index));
});
assets.unique();
var the_url = "{% url 'api-assets:systemuser-update-assets' pk=system_user.id %}";
var body = {"assets": assets};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PATCH'
});
$data_table.ajax.reload();
}
});
})
.on('click', '.btn_asset_delete', function () {
var $this = $(this);
var the_url = "{% url 'api-assets:systemuser-update-assets' pk=system_user.id %}";
var name = $(this).closest("tr").find(":nth-child(1) > a").html();
var $data_table = $("#system_user_list").DataTable();
var assets = [];
$('#system_user_list > tbody > tr').map(function () {
assets.push(parseInt($(this).closest("tr").find(":nth-child(1) > a").attr("data-aid")))
});
var delete_asset_id = $(this).data('aid');
assets.remove(delete_asset_id);
assets.unique();
var data = {"assets": assets};
objectDelete($this, name, the_url, data);
$data_table.ajax.reload();
})
.on('click', '#btn_add_user_group', function () {
jumpserver.assets_selected = {};
if (Object.keys(jumpserver.asset_groups_selected).length === 0) {
return false;
}
asset_groups = [];
$.ajax({
url: '{% url "api-assets:systemuser-update-assetgroups" pk=system_user.id %}',
method: 'GET',
dataType: 'json',
success: function (result) {
for (var i in result['asset_groups']) {
if (!isNaN(result['asset_groups'][i])) {
asset_groups.push(parseInt(result['asset_groups'][i]));
}
}
$.map(jumpserver.asset_groups_selected, function(value, index) {
asset_groups.push(parseInt(index));
});
asset_groups.unique();
console.log(asset_groups);
var the_url = '{% url "api-assets:systemuser-update-assetgroups" pk=system_user.id %}';
var body = {"asset_groups": asset_groups};
APIUpdateAttr({
url: the_url,
body: JSON.stringify(body),
method: 'PATCH'
});
{# TODO: reload the table #}
{# window.location.href="{% url 'assets:system-user-asset' pk=system_user.id %}"#}
}
});
})
.on('click', '.btn-leave-system_user', function () {
var $this = $(this);
var $tr = $this.closest('tr');
var $badge = $tr.find('.bdg_asset_groups');
var sid = $badge.data('gid');
var name = $badge.html() || $badge.text();
$('system-user-table').append(
'<option value="' + sid + '" id="opt_' + sid + '">' + name + '</option>'
);
$tr.remove();
var asset_groups = $('.bdg_asset_groups').map(function () {
return $(this).data('gid');
}).get();
updateSystemUserAssetGroup(asset_groups);
});
</script> </script>
{% endblock %} {% endblock %}

View File

@ -26,6 +26,19 @@
<tbody> <tbody>
</tbody> </tbody>
</table> </table>
<div id="actions" class="hide">
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Delete selected' %}</option>
<option value="update">{% trans 'Update selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-warning">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
@ -50,9 +63,73 @@
ajax_url: '{% url "api-assets:system-user-list" %}', ajax_url: '{% url "api-assets:system-user-list" %}',
columns: [{data: "id" }, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () { return "3"}}, columns: [{data: "id" }, {data: "name" }, {data: "username" }, {data: "assets_amount" }, {data: function () { return "3"}},
{data: "comment" }, {data: "id" }], {data: "comment" }, {data: "id" }],
op_html: $('#actions').html()
}; };
jumpserver.initDataTable(options); jumpserver.initDataTable(options);
})
.on('click', '.btn_admin_user_delete', function () {
var $this = $(this);
var $data_table = $('#idc_list_table').DataTable();
var name = $(this).closest("tr").find(":nth-child(2)").children('a').html();
var uid = $this.data('uid');
var the_url = '{% url "api-assets:system-user-detail" pk=99991937 %}'.replace('99991937', uid);
objectDelete($this, name, the_url);
$data_table.ajax.reload();
})
.on('click', '#btn_bulk_update', function () {
var action = $('#slct_bulk_update').val();
var $data_table = $('#system_user_list_table').DataTable();
var id_list = [];
var plain_id_list = [];
$data_table.rows({selected: true}).every(function(){
id_list.push({id: this.data().id});
plain_id_list.push(this.data().id);
}); });
if (id_list === []) {
return false;
}
var the_url = "{% url 'api-assets:system-user-list' %}";
function doDelete() {
swal({
title: "{% trans 'Are you sure?' %}",
text: "{% trans 'This will delete the selected System Users !!!' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "{% trans 'Confirm' %}",
closeOnConfirm: false
}, function() {
var success = function() {
var msg = "{% trans 'System Users Deleted.' %}";
swal("{% trans 'System Users Delete' %}", msg, "success");
$('#system_user_list_table').DataTable().ajax.reload();
};
var fail = function() {
var msg = "{% trans 'System Users Deleting failed.' %}";
swal("{% trans 'System Users Delete' %}", msg, "error");
};
var url_delete = the_url + '?id__in=' + JSON.stringify(plain_id_list);
APIUpdateAttr({url: url_delete, method: 'DELETE', success: success, error: fail});
$data_table.ajax.reload();
jumpserver.checked = false;
});
}
function doUpdate() {
{# TODO: bulk update the System Users #}
}
switch (action) {
case 'delete':
doDelete();
break;
case 'update':
doUpdate();
break;
default:
break;
}
})
</script> </script>
{% endblock %} {% endblock %}

View File

@ -2,16 +2,18 @@
from django.conf.urls import url from django.conf.urls import url
from .. import api from .. import api
from rest_framework import routers from rest_framework import routers
from rest_framework_bulk.routes import BulkRouter
app_name = 'assets' app_name = 'assets'
router = routers.DefaultRouter() router = BulkRouter()
router.register(r'v1/asset-groups', api.AssetGroupViewSet, 'asset-group') router.register(r'v1/asset-groups', api.AssetGroupViewSet, 'asset-group')
router.register(r'v1/assets', api.AssetViewSet, 'asset') router.register(r'v1/assets', api.AssetViewSet, 'asset')
router.register(r'v1/idc', api.IDCViewSet, 'idc') router.register(r'v1/idc', api.IDCViewSet, 'idc')
router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user') router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user')
router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user') router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user')
router.register(r'v1/tags', api.TagViewSet, 'asset-tag')
urlpatterns = [ urlpatterns = [
url(r'^v1/assets_bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'), url(r'^v1/assets_bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'),
@ -20,8 +22,31 @@ urlpatterns = [
name='system-user-auth-info'), name='system-user-auth-info'),
url(r'^v1/assets/(?P<pk>\d+)/groups/$', url(r'^v1/assets/(?P<pk>\d+)/groups/$',
api.AssetUpdateGroupApi.as_view(), name='asset-update-group'), api.AssetUpdateGroupApi.as_view(), name='asset-update-group'),
url(r'^v1/assets/(?P<pk>\d+)/system-users/$', url(r'^v1/assets/(?P<pk>\d+)/system-users/$',
api.SystemUserUpdateApi.as_view(), name='asset-update-system-users'), api.SystemUserUpdateApi.as_view(), name='asset-update-system-users'),
# update the system users, which add and delete the asset to the system user
url(r'^v1/system_user/(?P<pk>\d+)/assets/$',
api.SystemUserUpdateAssetsApi.as_view(), name='systemuser-update-assets'),
url(r'^v1/system_user/(?P<pk>\d+)/groups/$',
api.SystemUserUpdateAssetGroupApi.as_view(), name='systemuser-update-assetgroups'),
# update the asset group, which add or delete the asset to the group
url(r'^v1/groups/(?P<pk>\d+)/assets/$',
api.AssetGroupUpdateApi.as_view(), name='asset-groups-update'),
# update the asset group, and add or delete the system_user to the group
url(r'^v1/groups/(?P<pk>\d+)/system-users/$',
api.AssetGroupUpdateSystemUserApi.as_view(), name='asset-groups-update-systemusers'),
# update the IDC, and add or delete the assets to the IDC
url(r'^v1/idc/(?P<pk>\d+)/assets/$',
api.IDCupdateAssetsApi.as_view(), name='idc-update-assets'),
url(r'v1/tag/(?P<pk>\d+)/assets/$',
api.TagUpdateAssetsApi.as_view(), name='tag-update-assets'),
] ]
urlpatterns += router.urls urlpatterns += router.urls

View File

@ -16,7 +16,7 @@ from django.urls import reverse_lazy
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin from django.views.generic.detail import DetailView, SingleObjectMixin
from django.shortcuts import get_object_or_404, reverse, redirect from django.shortcuts import get_object_or_404, reverse, redirect
from django.http import HttpResponse, JsonResponse from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.views.decorators.csrf import csrf_protect, csrf_exempt from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.core.cache import cache from django.core.cache import cache
@ -37,8 +37,10 @@ class AssetListView(AdminUserRequiredMixin, TemplateView):
context = { context = {
'app': 'Assets', 'app': 'Assets',
'action': 'asset list', 'action': 'asset list',
'tag_list': [(i.id, i.name, i.asset_set.all().count())for i in Tag.objects.all().order_by('name')] 'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
'tag_list': [(i.id, i.name, i.assets.all().count())for i in Tag.objects.all().order_by('name')],
'tags': Tag.objects.all().order_by('name')
} }
kwargs.update(context) kwargs.update(context)
return super(AssetListView, self).get_context_data(**kwargs) return super(AssetListView, self).get_context_data(**kwargs)
@ -261,6 +263,8 @@ class AssetGroupListView(AdminUserRequiredMixin, TemplateView):
context = { context = {
'app': _('Assets'), 'app': _('Assets'),
'action': _('Asset group list'), 'action': _('Asset group list'),
'assets': Asset.objects.all(),
'system_users': SystemUser.objects.all(),
'keyword': self.request.GET.get('keyword', '') 'keyword': self.request.GET.get('keyword', '')
} }
kwargs.update(context) kwargs.update(context)
@ -280,6 +284,7 @@ class AssetGroupDetailView(AdminUserRequiredMixin, DetailView):
'app': _('Assets'), 'app': _('Assets'),
'action': _('Asset group detail'), 'action': _('Asset group detail'),
'assets_remain': assets_remain, 'assets_remain': assets_remain,
'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain],
'system_users': system_users, 'system_users': system_users,
'system_users_remain': system_users_remain, 'system_users_remain': system_users_remain,
} }
@ -383,6 +388,21 @@ class IDCAssetsView(AdminUserRequiredMixin, DetailView):
template_name = 'assets/idc_assets.html' template_name = 'assets/idc_assets.html'
context_object_name = 'idc' context_object_name = 'idc'
def get_context_data(self, **kwargs):
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
context = {
'app': _('Assets'),
'action': _('Asset detail'),
'groups': AssetGroup.objects.all(),
'system_users': SystemUser.objects.all(),
'tags': Tag.objects.all(),
'assets_remain': assets_remain,
'assets': [asset for asset in Asset.objects.all() if asset not in assets_remain],
}
kwargs.update(context)
return super(IDCAssetsView, self).get_context_data(**kwargs)
class IDCDeleteView(AdminUserRequiredMixin, DeleteView): class IDCDeleteView(AdminUserRequiredMixin, DeleteView):
model = IDC model = IDC
@ -477,10 +497,19 @@ class AdminUserDetailView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
def get_queryset(self): def get_queryset(self):
return self.object.assets.all() return self.object.assets.all()
# def get_asset_groups(self):
# return self.object.asset_groups.all()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
asset_groups = AssetGroup.objects.all()
assets = self.get_queryset()
context = { context = {
'app': 'assets', 'app': 'assets',
'action': 'Admin user detail' '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) kwargs.update(context)
return super(AdminUserDetailView, self).get_context_data(**kwargs) return super(AdminUserDetailView, self).get_context_data(**kwargs)
@ -630,7 +659,7 @@ class TagsListView(AdminUserRequiredMixin, ListView):
return super(TagsListView, self).get_context_data(**kwargs) return super(TagsListView, self).get_context_data(**kwargs)
class AssetTagCreateView(AdminUserRequiredMixin, CreateView): class AssetTagCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView):
model = Tag model = Tag
form_class = forms.AssetTagForm form_class = forms.AssetTagForm
template_name = 'assets/asset_tag_create.html' template_name = 'assets/asset_tag_create.html'
@ -653,7 +682,7 @@ class AssetTagCreateView(AdminUserRequiredMixin, CreateView):
assets_id_list = self.request.POST.getlist('assets', []) assets_id_list = self.request.POST.getlist('assets', [])
assets = [get_object_or_404(Asset, id=int(asset_id)) for asset_id in assets_id_list] assets = [get_object_or_404(Asset, id=int(asset_id)) for asset_id in assets_id_list]
asset_tag.created_by = self.request.user.username or 'Admin' asset_tag.created_by = self.request.user.username or 'Admin'
asset_tag.asset_set.add(*tuple(assets)) asset_tag.assets.add(*tuple(assets))
asset_tag.save() asset_tag.save()
return super(AssetTagCreateView, self).form_valid(form) return super(AssetTagCreateView, self).form_valid(form)
@ -667,13 +696,16 @@ class AssetTagDetailView(SingleObjectMixin, AdminUserRequiredMixin, ListView):
return super(AssetTagDetailView, self).get(request, *args, **kwargs) return super(AssetTagDetailView, self).get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
return self.object.asset_set.all() return self.object.assets.all()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
assets_remain = Asset.objects.exclude(id__in=self.object.assets.all())
context = { context = {
'app': _('Tag'), 'app': _('Tag'),
'action': _('Asset Tags detail'), 'action': _('Asset Tags detail'),
'asset_tag': self.object, '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) kwargs.update(context)
return super(AssetTagDetailView, self).get_context_data(**kwargs) return super(AssetTagDetailView, self).get_context_data(**kwargs)
@ -690,7 +722,7 @@ class AssetTagUpdateView(AdminUserRequiredMixin, UpdateView):
return super(AssetTagUpdateView, self).get(request, *args, **kwargs) return super(AssetTagUpdateView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
assets_all = self.object.asset_set.all() assets_all = self.object.assets.all()
context = { context = {
'app': _('Tag'), 'app': _('Tag'),
'action': _('Asset Tags detail'), 'action': _('Asset Tags detail'),
@ -710,6 +742,7 @@ class AssetTagDeleteView(AdminUserRequiredMixin, DeleteView):
@method_decorator(csrf_exempt, name='dispatch') @method_decorator(csrf_exempt, name='dispatch')
class AssetExportView(View): class AssetExportView(View):
@staticmethod @staticmethod
def get_asset_attr(asset, attr): def get_asset_attr(asset, attr):
if attr in ['admin_user', 'idc']: if attr in ['admin_user', 'idc']:

File diff suppressed because one or more lines are too long

View File

@ -2,9 +2,9 @@
# #
python ../apps/manage.py shell << EOF python ../apps/manage.py shell << EOF
from users.models import * from users.models.utils import *
generate_fake() generate_fake()
from assets.models import * from assets.models.utils import *
generate_fake() generate_fake()
EOF EOF