Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
3aea9941
Commit
3aea9941
authored
Nov 27, 2016
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
asset import
parent
c1c9c7b6
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
210 additions
and
67 deletions
+210
-67
forms.py
apps/assets/forms.py
+6
-2
models.py
apps/assets/models.py
+3
-3
serializers.py
apps/assets/serializers.py
+7
-7
_asset_import_modal.html
apps/assets/templates/assets/_asset_import_modal.html
+27
-0
asset_detail.html
apps/assets/templates/assets/asset_detail.html
+1
-1
asset_list.html
apps/assets/templates/assets/asset_list.html
+40
-20
views_urls.py
apps/assets/urls/views_urls.py
+2
-0
views.py
apps/assets/views.py
+111
-28
fake.json
apps/fixtures/fake.json
+0
-0
user_list.html
apps/users/templates/users/user_list.html
+1
-1
views_urls.py
apps/users/urls/views_urls.py
+1
-1
views.py
apps/users/views.py
+2
-2
clean_migrations.sh
utils/clean_migrations.sh
+1
-1
make_fake_json.sh
utils/make_fake_json.sh
+8
-1
No files found.
apps/assets/forms.py
View file @
3aea9941
...
...
@@ -309,4 +309,8 @@ class AssetTagForm(forms.ModelForm):
}
help_texts
=
{
'name'
:
'* required'
,
}
\ No newline at end of file
}
class
FileForm
(
forms
.
Form
):
file
=
forms
.
FileField
()
\ No newline at end of file
apps/assets/models.py
View file @
3aea9941
...
...
@@ -309,12 +309,12 @@ class Asset(models.Model):
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'
))
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
,
default
=
'I'
,
verbose_name
=
_
(
'Asset status'
))
status
=
models
.
CharField
(
choices
=
STATUS_CHOICES
,
max_length
=
8
,
null
=
True
,
blank
=
True
,
default
=
'I
n use
'
,
verbose_name
=
_
(
'Asset status'
))
type
=
models
.
CharField
(
choices
=
TYPE_CHOICES
,
max_length
=
16
,
blank
=
True
,
null
=
True
,
default
=
'Server'
,
verbose_name
=
_
(
'Asset type'
),)
env
=
models
.
CharField
(
choices
=
ENV_CHOICES
,
max_length
=
8
,
blank
=
True
,
null
=
True
,
default
=
'P'
,
verbose_name
=
_
(
'Asset environment'
),)
default
=
'P
rod
'
,
verbose_name
=
_
(
'Asset environment'
),)
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'
))
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Is active'
))
...
...
apps/assets/serializers.py
View file @
3aea9941
...
...
@@ -43,7 +43,6 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
# system_users = SystemUserSerializer(many=True, read_only=True)
# admin_user = AdminUserSerializer(many=False, read_only=True)
hardware
=
serializers
.
SerializerMethodField
()
type_display
=
serializers
.
SerializerMethodField
()
class
Meta
(
object
):
model
=
Asset
...
...
@@ -51,15 +50,16 @@ class AssetSerializer(BulkSerializerMixin, serializers.ModelSerializer):
@staticmethod
def
get_hardware
(
obj
):
return
'
%
s
%
s
%
s'
%
(
obj
.
cpu
,
obj
.
memory
,
obj
.
disk
)
@staticmethod
def
get_type_display
(
obj
):
if
obj
.
type
:
return
obj
.
type
.
value
if
obj
.
cpu
:
return
'
%
s
%
s
%
s'
%
(
obj
.
cpu
,
obj
.
memory
,
obj
.
disk
)
else
:
return
''
def
get_field_names
(
self
,
declared_fields
,
info
):
fields
=
super
(
AssetSerializer
,
self
)
.
get_field_names
(
declared_fields
,
info
)
fields
.
extend
([
'get_type_display'
,
'get_env_display'
])
return
fields
class
AssetGrantedSerializer
(
serializers
.
ModelSerializer
):
system_users
=
SystemUserSerializer
(
many
=
True
,
read_only
=
True
)
...
...
apps/assets/templates/assets/_asset_import_modal.html
0 → 100644
View file @
3aea9941
{% 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 %}
apps/assets/templates/assets/asset_detail.html
View file @
3aea9941
...
...
@@ -96,7 +96,7 @@
</tr>
<tr>
<td>
{% trans 'Asset status' %}:
</td>
<td><b>
{{ asset.
status
}}
</b></td>
<td><b>
{{ asset.
get_status_display()
}}
</b></td>
</tr>
<tr>
<td>
{% trans 'Is active' %}:
</td>
...
...
apps/assets/templates/assets/asset_list.html
View file @
3aea9941
...
...
@@ -48,7 +48,6 @@
{% 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"
><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"
>
<thead>
<tr>
...
...
@@ -81,6 +80,7 @@
</div>
</div>
</div>
{% include 'assets/_asset_import_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
...
...
@@ -100,7 +100,7 @@
}
else
{
oDiv
.
style
.
display
=
"none"
;
}
}
;
//onload;
}
//onload;
$
(
document
).
ready
(
function
(){
var
options
=
{
...
...
@@ -132,31 +132,51 @@
],
ajax_url
:
'{% url "api-assets:asset-list" %}'
,
columns
:
[{
data
:
"id"
},
{
data
:
"hostname"
},
{
data
:
"ip"
},
{
data
:
"port"
},
{
data
:
"
type_display"
},
{
data
:
"env"
},
{
data
:
"hardware"
},
{
data
:
"is_active"
},
{
data
:
"is_active"
},
{
data
:
"id"
}],
{
data
:
"
get_type_display"
},
{
data
:
"get_env_display"
},
{
data
:
"hardware"
},
{
data
:
"is_active"
},
{
data
:
"is_active"
},
{
data
:
"id"
}],
op_html
:
$
(
'#actions'
).
html
()
};
var
table
=
jumpserver
.
initDataTable
(
options
);
$
(
'.btn_export'
).
click
(
function
()
{
var
assets
=
[];
var
rows
=
table
.
rows
(
'.selected'
).
data
();
$
.
each
(
rows
,
function
(
index
,
obj
)
{
assets
.
push
(
obj
.
id
)
var
assets
=
[];
var
rows
=
table
.
rows
(
'.selected'
).
data
();
$
.
each
(
rows
,
function
(
index
,
obj
)
{
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
" %}"
,
method
:
'POST'
,
data
:
JSON
.
stringify
({
users_id
:
users
}),
dataType
:
"json"
,
success
:
function
(
data
,
textStatus
)
{
window
.
open
(
data
.
redirect
)
},
error
:
function
()
{
toastr
.
error
(
'Export failed'
);
$
(
'#btn_asset_import'
).
click
(
function
()
{
var
$form
=
$
(
'#fm_asset_import'
);
$form
.
find
(
'.help-block'
).
remove
();
function
success
(
data
)
{
if
(
data
.
valid
===
false
)
{
$
(
'<span />'
,
{
class
:
'help-block text-danger'
}).
html
(
data
.
msg
).
insertAfter
(
$
(
'#id_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>
...
...
apps/assets/urls/views_urls.py
View file @
3aea9941
...
...
@@ -9,6 +9,8 @@ urlpatterns = [
url
(
r'^$'
,
views
.
AssetListView
.
as_view
(),
name
=
'asset-index'
),
url
(
r'^asset/$'
,
views
.
AssetListView
.
as_view
(),
name
=
'asset-list'
),
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]+)/update/$'
,
views
.
AssetUpdateView
.
as_view
(),
name
=
'asset-update'
),
url
(
r'^asset/(?P<pk>[0-9]+)/delete/$'
,
views
.
AssetDeleteView
.
as_view
(),
name
=
'asset-delete'
),
...
...
apps/assets/views.py
View file @
3aea9941
...
...
@@ -9,6 +9,7 @@ from openpyxl import load_workbook
from
django.utils.translation
import
ugettext
as
_
from
django.conf
import
settings
from
django.db.models
import
Q
from
django.db
import
IntegrityError
from
django.views.generic
import
TemplateView
,
ListView
,
View
from
django.views.generic.edit
import
CreateView
,
DeleteView
,
FormView
,
UpdateView
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.utils
import
timezone
from
common.utils
import
int_seq
from
.utils
import
CreateAssetTagsMiXin
,
UpdateAssetTagsMiXin
from
.models
import
Asset
,
AssetGroup
,
IDC
,
AdminUser
,
SystemUser
,
Tag
from
.forms
import
*
from
common.mixins
import
JSONResponseMixin
from
common.utils
import
get_object_or_none
from
.utils
import
CreateAssetTagsMiXin
,
UpdateAssetTagsMiXin
from
.
import
forms
from
.models
import
Asset
,
AssetGroup
,
AdminUser
,
IDC
,
SystemUser
,
Tag
from
.hands
import
AdminUserRequiredMixin
...
...
@@ -45,7 +47,7 @@ class AssetListView(AdminUserRequiredMixin, TemplateView):
class
AssetCreateView
(
AdminUserRequiredMixin
,
CreateAssetTagsMiXin
,
CreateView
):
model
=
Asset
tag_type
=
'asset'
form_class
=
AssetCreateForm
form_class
=
forms
.
AssetCreateForm
template_name
=
'assets/asset_create.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
...
...
@@ -71,7 +73,7 @@ class AssetCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView):
class
AssetModalCreateView
(
AdminUserRequiredMixin
,
CreateAssetTagsMiXin
,
ListView
):
model
=
Asset
form_class
=
AssetCreateForm
form_class
=
forms
.
AssetCreateForm
template_name
=
'assets/asset_modal_update.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
...
...
@@ -99,7 +101,7 @@ class AssetModalCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, ListVie
class
AssetUpdateView
(
AdminUserRequiredMixin
,
UpdateAssetTagsMiXin
,
UpdateView
):
model
=
Asset
form_class
=
AssetCreateForm
form_class
=
forms
.
AssetCreateForm
template_name
=
'assets/asset_update.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
new_form
=
''
...
...
@@ -226,7 +228,7 @@ class AssetModalListView(AdminUserRequiredMixin, ListView):
class
AssetGroupCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
AssetGroup
form_class
=
AssetGroupForm
form_class
=
forms
.
AssetGroupForm
template_name
=
'assets/asset_group_create.html'
success_url
=
reverse_lazy
(
'assets:asset-group-list'
)
#ordering = '-id'
...
...
@@ -287,7 +289,7 @@ class AssetGroupDetailView(AdminUserRequiredMixin, DetailView):
class
AssetGroupUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
AssetGroup
form_class
=
AssetGroupForm
form_class
=
forms
.
AssetGroupForm
template_name
=
'assets/asset_group_create.html'
success_url
=
reverse_lazy
(
'assets:asset-group-list'
)
...
...
@@ -329,7 +331,7 @@ class IDCListView(AdminUserRequiredMixin, TemplateView):
class
IDCCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
IDC
form_class
=
IDCForm
form_class
=
forms
.
IDCForm
template_name
=
'assets/idc_create_update.html'
success_url
=
reverse_lazy
(
'assets:idc-list'
)
...
...
@@ -351,7 +353,7 @@ class IDCCreateView(AdminUserRequiredMixin, CreateView):
class
IDCUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
IDC
form_class
=
IDCForm
form_class
=
forms
.
IDCForm
template_name
=
'assets/idc_create_update.html'
context_object_name
=
'idc'
success_url
=
reverse_lazy
(
'assets:idc-list'
)
...
...
@@ -420,7 +422,7 @@ class AdminUserListView(AdminUserRequiredMixin, TemplateView):
class
AdminUserCreateView
(
AdminUserRequiredMixin
,
SuccessMessageMixin
,
CreateView
):
model
=
AdminUser
form_class
=
AdminUserForm
form_class
=
forms
.
AdminUserForm
template_name
=
'assets/admin_user_create_update.html'
success_url
=
reverse_lazy
(
'assets:admin-user-list'
)
...
...
@@ -446,7 +448,7 @@ class AdminUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVie
class
AdminUserUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
AdminUser
form_class
=
AdminUserForm
form_class
=
forms
.
AdminUserForm
template_name
=
'assets/admin_user_create_update.html'
def
get_context_data
(
self
,
**
kwargs
):
...
...
@@ -504,7 +506,7 @@ class SystemUserListView(AdminUserRequiredMixin, TemplateView):
class
SystemUserCreateView
(
AdminUserRequiredMixin
,
SuccessMessageMixin
,
CreateView
):
model
=
SystemUser
form_class
=
SystemUserForm
form_class
=
forms
.
SystemUserForm
template_name
=
'assets/system_user_create_update.html'
success_url
=
reverse_lazy
(
'assets:system-user-list'
)
...
...
@@ -528,7 +530,7 @@ class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVi
class
SystemUserUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
SystemUser
form_class
=
SystemUserForm
form_class
=
forms
.
SystemUserForm
template_name
=
'assets/system_user_create_update.html'
def
get_context_data
(
self
,
**
kwargs
):
...
...
@@ -630,7 +632,7 @@ class TagsListView(AdminUserRequiredMixin, ListView):
class
AssetTagCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
Tag
form_class
=
AssetTagForm
form_class
=
forms
.
AssetTagForm
template_name
=
'assets/asset_tag_create.html'
success_url
=
reverse_lazy
(
'assets:asset-tag-list'
)
#ordering = '-id'
...
...
@@ -679,7 +681,7 @@ class AssetTagDetailView(SingleObjectMixin, AdminUserRequiredMixin, ListView):
class
AssetTagUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
Tag
form_class
=
AssetTagForm
form_class
=
forms
.
AssetTagForm
template_name
=
'assets/asset_tag_create.html'
success_url
=
reverse_lazy
(
'assets:asset-tag-list'
)
...
...
@@ -707,13 +709,15 @@ class AssetTagDeleteView(AdminUserRequiredMixin, DeleteView):
@method_decorator
(
csrf_exempt
,
name
=
'dispatch'
)
class
ExportAsse
tView
(
View
):
class
AssetExpor
tView
(
View
):
@staticmethod
def
asset_g
et_attr
(
asset
,
attr
):
def
get_ass
et_attr
(
asset
,
attr
):
if
attr
in
[
'admin_user'
,
'idc'
]:
return
getattr
(
asset
,
attr
)
.
name
if
attr
in
[
'status'
,
'tyoe'
,
'env'
]:
return
getattr
(
asset
,
'get_{}_display'
)
elif
attr
in
[
'status'
,
'type'
,
'env'
]:
return
getattr
(
asset
,
'get_{}_display'
.
format
(
attr
))()
else
:
return
getattr
(
asset
,
attr
)
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
spm
=
request
.
GET
.
get
(
'spm'
,
''
)
...
...
@@ -725,16 +729,15 @@ class ExportAssetView(View):
wb
=
Workbook
()
ws
=
wb
.
active
ws
.
title
=
'Asset'
header
=
[
'hostname'
,
'ip'
,
'port'
,
'admin_user'
,
'system_users'
,
'idc'
,
'cpu'
,
'memory'
,
'disk'
,
'mac_address'
,
'other_ip'
,
'remote_card_ip'
,
'os'
,
'cabinet_no'
,
'cabinet_pos'
,
'number'
,
'status'
,
'type'
,
'env'
,
'sn'
,
'comment'
]
header
=
[
'hostname'
,
'ip'
,
'port'
,
'admin_user'
,
'idc'
,
'cpu'
,
'memory'
,
'disk'
,
'mac_address'
,
'other_ip'
,
'remote_card_ip'
,
'os'
,
'cabinet_no'
,
'cabinet_pos'
,
'number'
,
'status'
,
'type'
,
'env'
,
'sn'
,
'comment'
]
ws
.
append
(
header
)
for
asset
in
assets
:
ws
.
append
([
get
attr
(
asset
,
attr
)
for
attr
in
header
])
ws
.
append
([
self
.
get_asset_
attr
(
asset
,
attr
)
for
attr
in
header
])
filename
=
'
user
s-{}.xlsx'
.
format
(
timezone
.
localtime
(
timezone
.
now
())
.
strftime
(
'
%
Y-
%
m-
%
d_
%
H-
%
M-
%
S'
))
filename
=
'
asset
s-{}.xlsx'
.
format
(
timezone
.
localtime
(
timezone
.
now
())
.
strftime
(
'
%
Y-
%
m-
%
d_
%
H-
%
M-
%
S'
))
response
=
HttpResponse
(
save_virtual_workbook
(
wb
),
content_type
=
'application/vnd.ms-excel'
)
response
[
'Content-Disposition'
]
=
'attachment; filename="
%
s"'
%
filename
return
response
...
...
@@ -742,9 +745,89 @@ class ExportAssetView(View):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
try
:
assets_id
=
json
.
loads
(
request
.
body
)
.
get
(
'assets_id'
,
[])
print
(
assets_id
)
except
ValueError
:
return
HttpResponse
(
'Json object not valid'
,
status
=
400
)
spm
=
uuid
.
uuid4
()
.
get_hex
()
cache
.
set
(
spm
,
assets_id
,
300
)
url
=
reverse
(
'
users:export-user-csv
'
)
+
'?spm=
%
s'
%
spm
url
=
reverse
(
'
assets:asset-export
'
)
+
'?spm=
%
s'
%
spm
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
)
apps/fixtures/fake.json
View file @
3aea9941
This source diff could not be displayed because it is too large. You can
view the blob
instead.
apps/users/templates/users/user_list.html
View file @
3aea9941
...
...
@@ -99,7 +99,7 @@ $(document).ready(function(){
users
.
push
(
obj
.
id
)
});
$
.
ajax
({
url
:
"{% url
"
users
:
export
-
user
"
%}"
,
url
:
"{% url
'users:user-export'
%}"
,
method
:
'POST'
,
data
:
JSON
.
stringify
({
users_id
:
users
}),
dataType
:
"json"
,
...
...
apps/users/urls/views_urls.py
View file @
3aea9941
...
...
@@ -23,6 +23,7 @@ urlpatterns = [
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]+)/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'^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'),
...
...
@@ -40,5 +41,4 @@ urlpatterns = [
name
=
'user-group-asset-permission-create'
),
url
(
r'^user-group/(?P<pk>[0-9]+)/assets'
,
views
.
UserGroupGrantedAssetView
.
as_view
(),
name
=
'user-group-granted-asset'
),
url
(
r'^export/user/'
,
views
.
ExportUserView
.
as_view
(),
name
=
'export-user'
),
]
apps/users/views.py
View file @
3aea9941
...
...
@@ -557,7 +557,7 @@ class BulkImportUserView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
@method_decorator
(
csrf_exempt
,
name
=
'dispatch'
)
class
ExportUser
View
(
View
):
class
UserExport
View
(
View
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
spm
=
request
.
GET
.
get
(
'spm'
,
''
)
users_id
=
cache
.
get
(
spm
)
...
...
@@ -588,6 +588,6 @@ class ExportUserView(View):
return
HttpResponse
(
'Json object not valid'
,
status
=
400
)
spm
=
uuid
.
uuid4
()
.
get_hex
()
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
})
utils/clean_migrations.sh
View file @
3aea9941
...
...
@@ -2,5 +2,5 @@
#
for
app
in
users
assets perms audits teminal ops
;
do
rm
-f
$app
/migrations/000
*
rm
-f
../apps/
$app
/migrations/000
*
done
utils/make_fake_json.sh
View file @
3aea9941
#!/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
delete from django_content_type;
delete from auth_permission;
EOF
python ../apps/manage.py dumpdata
>
../apps/fixtures/
init
.json
python ../apps/manage.py dumpdata
>
../apps/fixtures/
fake
.json
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment