asset import

pull/530/head
ibuler 2016-11-27 14:37:50 +08:00
parent c1c9c7b68a
commit 3aea994101
14 changed files with 210 additions and 67 deletions

View File

@ -309,4 +309,8 @@ class AssetTagForm(forms.ModelForm):
} }
help_texts = { help_texts = {
'name': '* required', 'name': '* required',
} }
class FileForm(forms.Form):
file = forms.FileField()

View File

@ -309,12 +309,12 @@ class Asset(models.Model):
cabinet_no = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Cabinet number')) cabinet_no = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Cabinet number'))
cabinet_pos = models.IntegerField(null=True, blank=True, verbose_name=_('Cabinet position')) cabinet_pos = models.IntegerField(null=True, blank=True, verbose_name=_('Cabinet position'))
number = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Asset number')) number = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Asset number'))
status = models.CharField(choices=STATUS_CHOICES, max_length=1, null=True, blank=True, status = models.CharField(choices=STATUS_CHOICES, max_length=8, null=True, blank=True,
default='I', verbose_name=_('Asset status')) default='In use', verbose_name=_('Asset status'))
type = models.CharField(choices=TYPE_CHOICES, max_length=16, blank=True, null=True, type = models.CharField(choices=TYPE_CHOICES, max_length=16, blank=True, null=True,
default='Server', verbose_name=_('Asset type'),) default='Server', verbose_name=_('Asset type'),)
env = models.CharField(choices=ENV_CHOICES, max_length=8, blank=True, null=True, env = models.CharField(choices=ENV_CHOICES, max_length=8, blank=True, null=True,
default='P', verbose_name=_('Asset environment'),) default='Prod', verbose_name=_('Asset environment'),)
sn = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Serial number')) sn = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Serial number'))
created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by')) created_by = models.CharField(max_length=32, null=True, blank=True, verbose_name=_('Created by'))
is_active = models.BooleanField(default=True, verbose_name=_('Is active')) is_active = models.BooleanField(default=True, verbose_name=_('Is active'))

View File

@ -43,7 +43,6 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
# system_users = SystemUserSerializer(many=True, read_only=True) # system_users = SystemUserSerializer(many=True, read_only=True)
# admin_user = AdminUserSerializer(many=False, read_only=True) # admin_user = AdminUserSerializer(many=False, read_only=True)
hardware = serializers.SerializerMethodField() hardware = serializers.SerializerMethodField()
type_display = serializers.SerializerMethodField()
class Meta(object): class Meta(object):
model = Asset model = Asset
@ -51,15 +50,16 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
@staticmethod @staticmethod
def get_hardware(obj): def get_hardware(obj):
return '%s %s %s' % (obj.cpu, obj.memory, obj.disk) if obj.cpu:
return '%s %s %s' % (obj.cpu, obj.memory, obj.disk)
@staticmethod
def get_type_display(obj):
if obj.type:
return obj.type.value
else: else:
return '' return ''
def get_field_names(self, declared_fields, info):
fields = super(AssetSerializer, self).get_field_names(declared_fields, info)
fields.extend(['get_type_display', 'get_env_display'])
return fields
class AssetGrantedSerializer(serializers.ModelSerializer): class AssetGrantedSerializer(serializers.ModelSerializer):
system_users = SystemUserSerializer(many=True, read_only=True) system_users = SystemUserSerializer(many=True, read_only=True)

View File

@ -0,0 +1,27 @@
{% extends '_modal.html' %}
{% load i18n %}
{% block modal_id %}asset_import_modal{% endblock %}
{% block modal_title%}{% trans "Import asset" %}{% endblock %}
{% block modal_body %}
<p class="text-success">{% trans "Download template or use export excel format" %}</p>
<form method="post" action="{% url 'assets:asset-import' %}" id="fm_asset_import" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
<label class="control-label" for="id_assets">{% trans "Template" %}</label>
<a href="{{ MEDIA_URL }}files/asset_import_template.xlsx" style="display: block">{% trans 'Download' %}</a>
</div>
<div class="form-group">
<label class="control-label" for="id_users">{% trans "Asset excel file" %}</label>
<input id="id_assets" type="file" name="file" />
</div>
</form>
<p>
<p class="text-success" id="id_created"></p>
<p id="id_created_detail"></p>
<p class="text-warning" id="id_updated"></p>
<p id="id_updated_detail"></p>
<p class="text-danger" id="id_failed"></p>
<p id="id_failed_detail"></p>
</p>
{% endblock %}
{% block modal_confirm_id %}btn_asset_import{% endblock %}

View File

@ -96,7 +96,7 @@
</tr> </tr>
<tr> <tr>
<td>{% trans 'Asset status' %}:</td> <td>{% trans 'Asset status' %}:</td>
<td><b>{{ asset.status }}</b></td> <td><b>{{ asset.get_status_display() }}</b></td>
</tr> </tr>
<tr> <tr>
<td>{% trans 'Is active' %}:</td> <td>{% trans 'Is active' %}:</td>

View File

@ -48,7 +48,6 @@
{% block table_container %} {% block table_container %}
<div class="uc pull-left m-l-5 m-r-5"><a href="{% url "assets:asset-create" %}" class="btn btn-sm btn-primary"> {% trans "Create asset" %} </a></div> <div class="uc pull-left m-l-5 m-r-5"><a href="{% url "assets:asset-create" %}" class="btn btn-sm btn-primary"> {% trans "Create asset" %} </a></div>
<div class="uc pull-left"><a href="javascript:void(0);" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#asset_import_modal"> {% trans "Import asset" %} </a></div>
<table class="table table-striped table-bordered table-hover " id="asset_list_table" > <table class="table table-striped table-bordered table-hover " id="asset_list_table" >
<thead> <thead>
<tr> <tr>
@ -81,6 +80,7 @@
</div> </div>
</div> </div>
</div> </div>
{% include 'assets/_asset_import_modal.html' %}
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
@ -100,7 +100,7 @@
}else{ }else{
oDiv.style.display = "none"; oDiv.style.display = "none";
} }
}; //onload; } //onload;
$(document).ready(function(){ $(document).ready(function(){
var options = { var options = {
@ -132,31 +132,51 @@
], ],
ajax_url: '{% url "api-assets:asset-list" %}', ajax_url: '{% url "api-assets:asset-list" %}',
columns: [{data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "port" }, columns: [{data: "id"}, {data: "hostname" }, {data: "ip" }, {data: "port" },
{data: "type_display" }, {data: "env"}, {data: "hardware"}, {data: "is_active" }, {data: "get_type_display" }, {data: "get_env_display"}, {data: "hardware"},
{data: "is_active"}, {data: "id" }], {data: "is_active" }, {data: "is_active"}, {data: "id" }],
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)
});
$.ajax({
url: "{% url "assets:asset-export" %}",
method: 'POST',
data: JSON.stringify({assets_id: assets}),
dataType: "json",
success: function (data, textStatus) {
window.open(data.redirect)
},
error: function () {
toastr.error('Export failed');
}
})
}); });
$.ajax({
url: "{% url "assets:export-assets-xlsx" %}", $('#btn_asset_import').click(function() {
method: 'POST', var $form = $('#fm_asset_import');
data: JSON.stringify({users_id: users}), $form.find('.help-block').remove();
dataType: "json", function success (data) {
success: function (data, textStatus) { if (data.valid === false) {
window.open(data.redirect) $('<span />', {class: 'help-block text-danger'}).html(data.msg).insertAfter($('#id_users'));
}, } else {
error: function () { $('#id_created').html(data.created_info);
toastr.error('Export failed'); $('#id_created_detail').html(data.created.join(', '));
$('#id_updated').html(data.updated_info);
$('#id_updated_detail').html(data.updated.join(', '));
$('#id_failed').html(data.failed_info);
$('#id_failed_detail').html(data.failed.join(', '));
var $data_table = $('#asset_list_table').DataTable();
$data_table.ajax.reload();
} }
}) }
}); $form.ajaxSubmit({success: success});
})
}); });
</script> </script>

View File

@ -9,6 +9,8 @@ urlpatterns = [
url(r'^$', views.AssetListView.as_view(), name='asset-index'), url(r'^$', views.AssetListView.as_view(), name='asset-index'),
url(r'^asset/$', views.AssetListView.as_view(), name='asset-list'), url(r'^asset/$', views.AssetListView.as_view(), name='asset-list'),
url(r'^asset/create/$', views.AssetCreateView.as_view(), name='asset-create'), url(r'^asset/create/$', views.AssetCreateView.as_view(), name='asset-create'),
url(r'^asset/export/$', views.AssetExportView.as_view(), name='asset-export'),
url(r'^asset/import/$', views.BulkImportAssetView.as_view(), name='asset-import'),
url(r'^asset/(?P<pk>[0-9]+)/$', views.AssetDetailView.as_view(), name='asset-detail'), url(r'^asset/(?P<pk>[0-9]+)/$', views.AssetDetailView.as_view(), name='asset-detail'),
url(r'^asset/(?P<pk>[0-9]+)/update/$', views.AssetUpdateView.as_view(), name='asset-update'), url(r'^asset/(?P<pk>[0-9]+)/update/$', views.AssetUpdateView.as_view(), name='asset-update'),
url(r'^asset/(?P<pk>[0-9]+)/delete/$', views.AssetDeleteView.as_view(), name='asset-delete'), url(r'^asset/(?P<pk>[0-9]+)/delete/$', views.AssetDeleteView.as_view(), name='asset-delete'),

View File

@ -9,6 +9,7 @@ from openpyxl import load_workbook
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.conf import settings from django.conf import settings
from django.db.models import Q from django.db.models import Q
from django.db import IntegrityError
from django.views.generic import TemplateView, ListView, View from django.views.generic import TemplateView, ListView, View
from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView from django.views.generic.edit import CreateView, DeleteView, FormView, UpdateView
from django.urls import reverse_lazy from django.urls import reverse_lazy
@ -21,10 +22,11 @@ from django.utils.decorators import method_decorator
from django.core.cache import cache from django.core.cache import cache
from django.utils import timezone from django.utils import timezone
from common.utils import int_seq from common.mixins import JSONResponseMixin
from .utils import CreateAssetTagsMiXin,UpdateAssetTagsMiXin from common.utils import get_object_or_none
from .models import Asset, AssetGroup, IDC, AdminUser, SystemUser, Tag from .utils import CreateAssetTagsMiXin, UpdateAssetTagsMiXin
from .forms import * from . import forms
from .models import Asset, AssetGroup, AdminUser, IDC, SystemUser, Tag
from .hands import AdminUserRequiredMixin from .hands import AdminUserRequiredMixin
@ -45,7 +47,7 @@ class AssetListView(AdminUserRequiredMixin, TemplateView):
class AssetCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView): class AssetCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView):
model = Asset model = Asset
tag_type = 'asset' tag_type = 'asset'
form_class = AssetCreateForm form_class = forms.AssetCreateForm
template_name = 'assets/asset_create.html' template_name = 'assets/asset_create.html'
success_url = reverse_lazy('assets:asset-list') success_url = reverse_lazy('assets:asset-list')
@ -71,7 +73,7 @@ class AssetCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView):
class AssetModalCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, ListView): class AssetModalCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, ListView):
model = Asset model = Asset
form_class = AssetCreateForm form_class = forms.AssetCreateForm
template_name = 'assets/asset_modal_update.html' template_name = 'assets/asset_modal_update.html'
success_url = reverse_lazy('assets:asset-list') success_url = reverse_lazy('assets:asset-list')
@ -99,7 +101,7 @@ class AssetModalCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, ListVie
class AssetUpdateView(AdminUserRequiredMixin, UpdateAssetTagsMiXin, UpdateView): class AssetUpdateView(AdminUserRequiredMixin, UpdateAssetTagsMiXin, UpdateView):
model = Asset model = Asset
form_class = AssetCreateForm form_class = forms.AssetCreateForm
template_name = 'assets/asset_update.html' template_name = 'assets/asset_update.html'
success_url = reverse_lazy('assets:asset-list') success_url = reverse_lazy('assets:asset-list')
new_form = '' new_form = ''
@ -226,7 +228,7 @@ class AssetModalListView(AdminUserRequiredMixin, ListView):
class AssetGroupCreateView(AdminUserRequiredMixin, CreateView): class AssetGroupCreateView(AdminUserRequiredMixin, CreateView):
model = AssetGroup model = AssetGroup
form_class = AssetGroupForm form_class = forms.AssetGroupForm
template_name = 'assets/asset_group_create.html' template_name = 'assets/asset_group_create.html'
success_url = reverse_lazy('assets:asset-group-list') success_url = reverse_lazy('assets:asset-group-list')
#ordering = '-id' #ordering = '-id'
@ -287,7 +289,7 @@ class AssetGroupDetailView(AdminUserRequiredMixin, DetailView):
class AssetGroupUpdateView(AdminUserRequiredMixin, UpdateView): class AssetGroupUpdateView(AdminUserRequiredMixin, UpdateView):
model = AssetGroup model = AssetGroup
form_class = AssetGroupForm form_class = forms.AssetGroupForm
template_name = 'assets/asset_group_create.html' template_name = 'assets/asset_group_create.html'
success_url = reverse_lazy('assets:asset-group-list') success_url = reverse_lazy('assets:asset-group-list')
@ -329,7 +331,7 @@ class IDCListView(AdminUserRequiredMixin, TemplateView):
class IDCCreateView(AdminUserRequiredMixin, CreateView): class IDCCreateView(AdminUserRequiredMixin, CreateView):
model = IDC model = IDC
form_class = IDCForm form_class = forms.IDCForm
template_name = 'assets/idc_create_update.html' template_name = 'assets/idc_create_update.html'
success_url = reverse_lazy('assets:idc-list') success_url = reverse_lazy('assets:idc-list')
@ -351,7 +353,7 @@ class IDCCreateView(AdminUserRequiredMixin, CreateView):
class IDCUpdateView(AdminUserRequiredMixin, UpdateView): class IDCUpdateView(AdminUserRequiredMixin, UpdateView):
model = IDC model = IDC
form_class = IDCForm form_class = forms.IDCForm
template_name = 'assets/idc_create_update.html' template_name = 'assets/idc_create_update.html'
context_object_name = 'idc' context_object_name = 'idc'
success_url = reverse_lazy('assets:idc-list') success_url = reverse_lazy('assets:idc-list')
@ -420,7 +422,7 @@ class AdminUserListView(AdminUserRequiredMixin, TemplateView):
class AdminUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView): class AdminUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = AdminUser model = AdminUser
form_class = AdminUserForm form_class = forms.AdminUserForm
template_name = 'assets/admin_user_create_update.html' template_name = 'assets/admin_user_create_update.html'
success_url = reverse_lazy('assets:admin-user-list') success_url = reverse_lazy('assets:admin-user-list')
@ -446,7 +448,7 @@ class AdminUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVie
class AdminUserUpdateView(AdminUserRequiredMixin, UpdateView): class AdminUserUpdateView(AdminUserRequiredMixin, UpdateView):
model = AdminUser model = AdminUser
form_class = AdminUserForm form_class = forms.AdminUserForm
template_name = 'assets/admin_user_create_update.html' template_name = 'assets/admin_user_create_update.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -504,7 +506,7 @@ class SystemUserListView(AdminUserRequiredMixin, TemplateView):
class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView): class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
model = SystemUser model = SystemUser
form_class = SystemUserForm form_class = forms.SystemUserForm
template_name = 'assets/system_user_create_update.html' template_name = 'assets/system_user_create_update.html'
success_url = reverse_lazy('assets:system-user-list') success_url = reverse_lazy('assets:system-user-list')
@ -528,7 +530,7 @@ class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVi
class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView): class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView):
model = SystemUser model = SystemUser
form_class = SystemUserForm form_class = forms.SystemUserForm
template_name = 'assets/system_user_create_update.html' template_name = 'assets/system_user_create_update.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -630,7 +632,7 @@ class TagsListView(AdminUserRequiredMixin, ListView):
class AssetTagCreateView(AdminUserRequiredMixin, CreateView): class AssetTagCreateView(AdminUserRequiredMixin, CreateView):
model = Tag model = Tag
form_class = AssetTagForm form_class = forms.AssetTagForm
template_name = 'assets/asset_tag_create.html' template_name = 'assets/asset_tag_create.html'
success_url = reverse_lazy('assets:asset-tag-list') success_url = reverse_lazy('assets:asset-tag-list')
#ordering = '-id' #ordering = '-id'
@ -679,7 +681,7 @@ class AssetTagDetailView(SingleObjectMixin, AdminUserRequiredMixin, ListView):
class AssetTagUpdateView(AdminUserRequiredMixin, UpdateView): class AssetTagUpdateView(AdminUserRequiredMixin, UpdateView):
model = Tag model = Tag
form_class = AssetTagForm form_class = forms.AssetTagForm
template_name = 'assets/asset_tag_create.html' template_name = 'assets/asset_tag_create.html'
success_url = reverse_lazy('assets:asset-tag-list') success_url = reverse_lazy('assets:asset-tag-list')
@ -707,13 +709,15 @@ class AssetTagDeleteView(AdminUserRequiredMixin, DeleteView):
@method_decorator(csrf_exempt, name='dispatch') @method_decorator(csrf_exempt, name='dispatch')
class ExportAssetView(View): class AssetExportView(View):
@staticmethod @staticmethod
def asset_get_attr(asset, attr): def get_asset_attr(asset, attr):
if attr in ['admin_user', 'idc']: if attr in ['admin_user', 'idc']:
return getattr(asset, attr).name return getattr(asset, attr).name
if attr in ['status', 'tyoe', 'env']: elif attr in ['status', 'type', 'env']:
return getattr(asset, 'get_{}_display') return getattr(asset, 'get_{}_display'.format(attr))()
else:
return getattr(asset, attr)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
spm = request.GET.get('spm', '') spm = request.GET.get('spm', '')
@ -725,16 +729,15 @@ class ExportAssetView(View):
wb = Workbook() wb = Workbook()
ws = wb.active ws = wb.active
ws.title = 'Asset' ws.title = 'Asset'
header = ['hostname', 'ip', 'port', 'admin_user', 'system_users', 'idc', header = ['hostname', 'ip', 'port', 'admin_user', 'idc', 'cpu', 'memory', 'disk',
'cpu', 'memory', 'disk', 'mac_address', 'other_ip', 'remote_card_ip', 'mac_address', 'other_ip', 'remote_card_ip', 'os', 'cabinet_no',
'os', 'cabinet_no', 'cabinet_pos', 'number', 'status', 'type', 'env', 'cabinet_pos', 'number', 'status', 'type', 'env', 'sn', 'comment']
'sn', 'comment']
ws.append(header) ws.append(header)
for asset in assets: for asset in assets:
ws.append([getattr(asset, attr) for attr in header]) ws.append([self.get_asset_attr(asset, attr) for attr in header])
filename = 'users-{}.xlsx'.format(timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S')) filename = 'assets-{}.xlsx'.format(timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S'))
response = HttpResponse(save_virtual_workbook(wb), content_type='application/vnd.ms-excel') response = HttpResponse(save_virtual_workbook(wb), content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename="%s"' % filename response['Content-Disposition'] = 'attachment; filename="%s"' % filename
return response return response
@ -742,9 +745,89 @@ class ExportAssetView(View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
try: try:
assets_id = json.loads(request.body).get('assets_id', []) assets_id = json.loads(request.body).get('assets_id', [])
print(assets_id)
except ValueError: except ValueError:
return HttpResponse('Json object not valid', status=400) return HttpResponse('Json object not valid', status=400)
spm = uuid.uuid4().get_hex() spm = uuid.uuid4().get_hex()
cache.set(spm, assets_id, 300) cache.set(spm, assets_id, 300)
url = reverse('users:export-user-csv') + '?spm=%s' % spm url = reverse('assets:asset-export') + '?spm=%s' % spm
return JsonResponse({'redirect': url}) return JsonResponse({'redirect': url})
class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
form_class = forms.FileForm
def form_valid(self, form):
try:
wb = load_workbook(form.cleaned_data['file'])
ws = wb.get_active_sheet()
except Exception as e:
print(e)
data = {'valid': False, 'msg': 'Not a valid Excel file'}
return self.render_json_response(data)
rows = ws.rows
header_all = ['hostname', 'ip', 'port', 'admin_user', 'idc', 'cpu', 'memory', 'disk',
'mac_address', 'other_ip', 'remote_card_ip', 'os', 'cabinet_no',
'cabinet_pos', 'number', 'status', 'type', 'env', 'sn', 'comment']
header_min = ['hostname', 'ip', 'port', 'admin_user', 'comment']
header = [col.value for col in next(rows)]
if header not in header_all and header_min not in header:
data = {'valid': False, 'msg': 'Must be same format as template or export file'}
return self.render_json_response(data)
created = []
updated = []
failed = []
for row in rows:
asset_dict = dict(zip(header, [col.value for col in row]))
if asset_dict.get('admin_user', None):
admin_user = get_object_or_none(AdminUser, name=asset_dict['admin_user'])
asset_dict['admin_user'] = admin_user
if asset_dict.get('idc'):
idc = get_object_or_none(IDC, name=asset_dict['idc'])
asset_dict['idc'] = idc
if asset_dict.get('type'):
asset_display_type_map = dict(zip(dict(Asset.TYPE_CHOICES).values, dict(Asset.TYPE_CHOICES).keys()))
asset_type = asset_display_type_map.get(asset_dict['type'], 'Server')
asset_dict['type'] = asset_type
if asset_dict.get('status'):
asset_display_status_map = dict(zip(dict(Asset.STATUS_CHOICES).values,
dict(Asset.STATUS_CHOICES).keys()))
asset_status = asset_display_status_map.get(asset_dict['status'], 'In use')
asset_dict['status'] = asset_status
if asset_dict.get('env'):
asset_display_env_map = dict(zip(dict(Asset.ENV_CHOICES).values(),
dict(Asset.ENV_CHOICES).keys()))
asset_env = asset_display_env_map.get(asset_dict['env'], 'Prod')
asset_dict['env'] = asset_env
try:
Asset.objects.create(**asset_dict)
created.append(asset_dict['ip'])
except IntegrityError as e:
asset = Asset.objects.filter(ip=asset_dict['ip'], port=asset_dict['port'])
if not asset:
failed.append(asset_dict['ip'])
continue
asset.update(**asset_dict)
updated.append(asset_dict['ip'])
except TypeError as e:
print(e)
failed.append(asset_dict['ip'])
data = {
'created': created,
'created_info': 'Created {}'.format(len(created)),
'updated': updated,
'updated_info': 'Updated {}'.format(len(updated)),
'failed': failed,
'failed_info': 'Failed {}'.format(len(failed)),
'valid': True,
'msg': 'Created: {}. Updated: {}, Error: {}'.format(len(created), len(updated), len(failed))
}
return self.render_json_response(data)

File diff suppressed because one or more lines are too long

View File

@ -99,7 +99,7 @@ $(document).ready(function(){
users.push(obj.id) users.push(obj.id)
}); });
$.ajax({ $.ajax({
url: "{% url "users:export-user" %}", url: "{% url 'users:user-export' %}",
method: 'POST', method: 'POST',
data: JSON.stringify({users_id: users}), data: JSON.stringify({users_id: users}),
dataType: "json", dataType: "json",

View File

@ -23,6 +23,7 @@ urlpatterns = [
name='user-asset-permission-create'), name='user-asset-permission-create'),
url(r'^user/(?P<pk>[0-9]+)/assets', views.UserGrantedAssetView.as_view(), name='user-granted-asset'), url(r'^user/(?P<pk>[0-9]+)/assets', views.UserGrantedAssetView.as_view(), name='user-granted-asset'),
url(r'^user/(?P<pk>[0-9]+)/login-history', views.UserDetailView.as_view(), name='user-login-history'), url(r'^user/(?P<pk>[0-9]+)/login-history', views.UserDetailView.as_view(), name='user-login-history'),
url(r'^user/export/', views.UserExportView.as_view(), name='user-export'),
url(r'^first-login/$', views.UserFirstLoginView.as_view(), name='user-first-login'), url(r'^first-login/$', views.UserFirstLoginView.as_view(), name='user-first-login'),
url(r'^user/import/$', views.BulkImportUserView.as_view(), name='user-import'), url(r'^user/import/$', views.BulkImportUserView.as_view(), name='user-import'),
# url(r'^user/(?P<pk>[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'), # url(r'^user/(?P<pk>[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'),
@ -40,5 +41,4 @@ urlpatterns = [
name='user-group-asset-permission-create'), name='user-group-asset-permission-create'),
url(r'^user-group/(?P<pk>[0-9]+)/assets', views.UserGroupGrantedAssetView.as_view(), url(r'^user-group/(?P<pk>[0-9]+)/assets', views.UserGroupGrantedAssetView.as_view(),
name='user-group-granted-asset'), name='user-group-granted-asset'),
url(r'^export/user/', views.ExportUserView.as_view(), name='export-user'),
] ]

View File

@ -557,7 +557,7 @@ class BulkImportUserView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
@method_decorator(csrf_exempt, name='dispatch') @method_decorator(csrf_exempt, name='dispatch')
class ExportUserView(View): class UserExportView(View):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
spm = request.GET.get('spm', '') spm = request.GET.get('spm', '')
users_id = cache.get(spm) users_id = cache.get(spm)
@ -588,6 +588,6 @@ class ExportUserView(View):
return HttpResponse('Json object not valid', status=400) return HttpResponse('Json object not valid', status=400)
spm = uuid.uuid4().get_hex() spm = uuid.uuid4().get_hex()
cache.set(spm, users_id, 300) cache.set(spm, users_id, 300)
url = reverse('users:export-user-csv') + '?spm=%s' % spm url = reverse('users:user-export') + '?spm=%s' % spm
return JsonResponse({'redirect': url}) return JsonResponse({'redirect': url})

View File

@ -2,5 +2,5 @@
# #
for app in users assets perms audits teminal ops;do for app in users assets perms audits teminal ops;do
rm -f $app/migrations/000* rm -f ../apps/$app/migrations/000*
done done

View File

@ -1,10 +1,17 @@
#!/bin/bash #!/bin/bash
# #
python ../apps/manage.py shell << EOF
from users.models import *
generate_fake()
from assets.models import *
generate_fake()
EOF
python ../apps/manage.py dbshell << EOF python ../apps/manage.py dbshell << EOF
delete from django_content_type; delete from django_content_type;
delete from auth_permission; delete from auth_permission;
EOF EOF
python ../apps/manage.py dumpdata > ../apps/fixtures/init.json python ../apps/manage.py dumpdata > ../apps/fixtures/fake.json