Commit 3aea9941 authored by ibuler's avatar ibuler

asset import

parent c1c9c7b6
...@@ -310,3 +310,7 @@ class AssetTagForm(forms.ModelForm): ...@@ -310,3 +310,7 @@ class AssetTagForm(forms.ModelForm):
help_texts = { help_texts = {
'name': '* required', 'name': '* required',
} }
class FileForm(forms.Form):
file = forms.FileField()
\ No newline at end of file
...@@ -309,12 +309,12 @@ class Asset(models.Model): ...@@ -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'))
......
...@@ -43,7 +43,6 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer): ...@@ -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): ...@@ -51,15 +50,16 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
@staticmethod @staticmethod
def get_hardware(obj): def get_hardware(obj):
if obj.cpu:
return '%s %s %s' % (obj.cpu, obj.memory, obj.disk) 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)
......
{% 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 %}
...@@ -96,7 +96,7 @@ ...@@ -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>
......
...@@ -48,7 +48,6 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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,8 +132,8 @@ ...@@ -132,8 +132,8 @@
], ],
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);
...@@ -145,9 +145,9 @@ ...@@ -145,9 +145,9 @@
assets.push(obj.id) assets.push(obj.id)
}); });
$.ajax({ $.ajax({
url: "{% url "assets:export-assets-xlsx" %}", url: "{% url "assets:asset-export" %}",
method: 'POST', method: 'POST',
data: JSON.stringify({users_id: users}), data: JSON.stringify({assets_id: assets}),
dataType: "json", dataType: "json",
success: function (data, textStatus) { success: function (data, textStatus) {
window.open(data.redirect) window.open(data.redirect)
...@@ -158,6 +158,26 @@ ...@@ -158,6 +158,26 @@
}) })
}); });
$('#btn_asset_import').click(function() {
var $form = $('#fm_asset_import');
$form.find('.help-block').remove();
function success (data) {
if (data.valid === false) {
$('<span />', {class: 'help-block text-danger'}).html(data.msg).insertAfter($('#id_users'));
} else {
$('#id_created').html(data.created_info);
$('#id_created_detail').html(data.created.join(', '));
$('#id_updated').html(data.updated_info);
$('#id_updated_detail').html(data.updated.join(', '));
$('#id_failed').html(data.failed_info);
$('#id_failed_detail').html(data.failed.join(', '));
var $data_table = $('#asset_list_table').DataTable();
$data_table.ajax.reload();
}
}
$form.ajaxSubmit({success: success});
})
}); });
</script> </script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -9,6 +9,8 @@ urlpatterns = [ ...@@ -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'),
......
This diff is collapsed.
This diff is collapsed.
...@@ -99,7 +99,7 @@ $(document).ready(function(){ ...@@ -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",
......
...@@ -23,6 +23,7 @@ urlpatterns = [ ...@@ -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 = [ ...@@ -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'),
] ]
...@@ -557,7 +557,7 @@ class BulkImportUserView(AdminUserRequiredMixin, JSONResponseMixin, FormView): ...@@ -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): ...@@ -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})
...@@ -2,5 +2,5 @@ ...@@ -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
#!/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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment