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
cb902362
Commit
cb902362
authored
Jan 26, 2018
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Feature] 资产列表标签搜索
parent
7433327d
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
141 additions
and
36 deletions
+141
-36
api.py
apps/assets/api.py
+2
-1
forms.py
apps/assets/forms.py
+35
-13
asset_create.html
apps/assets/templates/assets/asset_create.html
+27
-11
asset_list.html
apps/assets/templates/assets/asset_list.html
+22
-0
utils.py
apps/assets/utils.py
+26
-1
asset.py
apps/assets/views/asset.py
+9
-7
jumpserver.css
apps/static/css/jumpserver.css
+3
-2
jumpserver.js
apps/static/js/jumpserver.js
+17
-1
No files found.
apps/assets/api.py
View file @
cb902362
...
...
@@ -30,12 +30,13 @@ from . import serializers
from
.tasks
import
update_asset_hardware_info_manual
,
test_admin_user_connectability_manual
,
\
test_asset_connectability_manual
,
push_system_user_to_cluster_assets_manual
,
\
test_system_user_connectability_manual
from
.utils
import
LabelFilter
logger
=
get_logger
(
__file__
)
class
AssetViewSet
(
CustomFilterMixin
,
BulkModelViewSet
):
class
AssetViewSet
(
CustomFilterMixin
,
LabelFilter
,
BulkModelViewSet
):
"""
API endpoint that allows Asset to be viewed or edited.
"""
...
...
apps/assets/forms.py
View file @
cb902362
...
...
@@ -5,7 +5,6 @@ from django.utils.translation import gettext_lazy as _
from
.models
import
Cluster
,
Asset
,
AssetGroup
,
AdminUser
,
SystemUser
,
Label
from
common.utils
import
validate_ssh_private_key
,
ssh_pubkey_gen
,
ssh_key_gen
,
get_logger
logger
=
get_logger
(
__file__
)
...
...
@@ -19,10 +18,18 @@ class AssetCreateForm(forms.ModelForm):
]
widgets
=
{
'groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select asset groups'
)}),
'cluster'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select cluster'
)}),
'admin_user'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select admin user'
)}),
'labels'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select labels'
)}),
'groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select asset groups'
)
}),
'cluster'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select cluster'
)
}),
'admin_user'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select admin user'
)
}),
'labels'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select labels'
)
}),
'port'
:
forms
.
TextInput
(),
}
help_texts
=
{
...
...
@@ -40,9 +47,13 @@ class AssetCreateForm(forms.ModelForm):
raise
forms
.
ValidationError
(
_
(
"You need set a admin user if cluster not have"
))
return
self
.
cleaned_data
[
'admin_user'
]
def
save
(
self
,
commit
=
True
):
print
(
self
.
cleaned_data
)
return
super
()
.
save
(
commit
=
commit
)
def
is_valid
(
self
):
print
(
self
.
data
)
result
=
super
()
.
is_valid
()
if
not
result
:
print
(
self
.
errors
)
print
(
self
.
cleaned_data
)
return
result
class
AssetUpdateForm
(
forms
.
ModelForm
):
...
...
@@ -54,8 +65,19 @@ class AssetUpdateForm(forms.ModelForm):
'cabinet_pos'
,
'number'
,
'comment'
,
'admin_user'
,
'labels'
]
widgets
=
{
'groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select asset groups'
)}),
'admin_user'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
"Default using cluster admin user"
)})
'groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select asset groups'
)
}),
'cluster'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select cluster'
)
}),
'admin_user'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select admin user'
)
}),
'labels'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select labels'
)
}),
'port'
:
forms
.
TextInput
(),
}
help_texts
=
{
'hostname'
:
'* required'
,
...
...
@@ -72,9 +94,9 @@ class AssetUpdateForm(forms.ModelForm):
raise
forms
.
ValidationError
(
_
(
"You need set a admin user if cluster not have"
))
return
self
.
cleaned_data
[
'admin_user'
]
def
save
(
self
,
commit
=
True
):
print
(
self
.
cleaned_
data
)
return
super
()
.
save
(
commit
=
commit
)
def
is_valid
(
self
):
print
(
self
.
data
)
return
super
()
.
is_valid
(
)
class
AssetBulkUpdateForm
(
forms
.
ModelForm
):
...
...
apps/assets/templates/assets/asset_create.html
View file @
cb902362
...
...
@@ -32,25 +32,31 @@
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Labels' %}
</h3>
<div
class=
"form-group"
>
<div
class=
"form-group
{% if form.errors.labels %} has-error {% endif %}
"
>
<label
for=
"{{ form.labels.id_for_label }}"
class=
"col-md-2 control-label"
>
{% trans 'Labels' %}
</label>
<div
class=
"col-md-9"
>
<select
name=
"labels"
class=
"select2"
data-placeholder=
"Select labels"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
id=
"{{ form.labels.id_for_label }}"
>
<select
name=
"labels"
class=
"select2
labels
"
data-placeholder=
"Select labels"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
id=
"{{ form.labels.id_for_label }}"
>
{% for name, labels in form.labels.field.queryset|group_labels %}
<optgroup
label=
"{{ name }}"
>
{% for label in labels %}
{% if label in form.labels.initial %}
<option
value=
"{{ label.id }}"
selected
>
{{ label.
name }}:{{ label.
value }}
</option>
<option
value=
"{{ label.id }}"
selected
>
{{ label.value }}
</option>
{% else %}
<option
value=
"{{ label.id }}"
>
{{ label.
name }}:{{ label.
value }}
</option>
<option
value=
"{{ label.id }}"
>
{{ label.value }}
</option>
{% endif %}
{% endfor %}
</optgroup>
{% endfor %}
</select>
{% if form.errors.labels %}
{% for e in form.errors.labels %}
<div
class=
"help-block"
>
{{ e }}
</div>
{% endfor %}
{% endif %}
</div>
</div>
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
{% bootstrap_field form.comment layout="horizontal" %}
...
...
@@ -67,11 +73,20 @@
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
ready
(
function
()
{
$
(
'.select2'
).
select2
({
allowClear
:
true
});
})
</script>
<script>
function
format
(
item
)
{
var
group
=
item
.
element
.
parentElement
.
label
;
return
group
+
':'
+
item
.
text
;
}
$
(
document
).
ready
(
function
()
{
$
(
'.select2'
).
select2
({
allowClear
:
true
});
$
(
".labels"
).
select2
({
allowClear
:
true
,
templateSelection
:
format
});
})
</script>
{% endblock %}
\ No newline at end of file
apps/assets/templates/assets/asset_list.html
View file @
cb902362
...
...
@@ -23,6 +23,14 @@
{% block table_container %}
<div
class=
"uc pull-left m-r-5"
><a
href=
"{% url "
assets:asset-create
"
%}"
class=
"btn btn-sm btn-primary"
>
{% trans "Create asset" %}
</a></div>
<div
class=
"btn-group"
style=
"float: right"
>
<button
data-toggle=
"dropdown"
class=
"btn btn-default btn-sm dropdown-toggle"
>
{% trans 'Label' %}
<span
class=
"caret"
></span></button>
<ul
class=
"dropdown-menu labels"
>
{% for label in labels %}
<li><a
style=
"font-weight: bolder"
>
{{ label.name }}:{{ label.value }}
</a></li>
{% endfor %}
</ul>
</div>
<table
class=
"table table-striped table-bordered table-hover "
id=
"asset_list_table"
>
<thead>
<tr>
...
...
@@ -114,6 +122,20 @@ function initTable() {
$
(
document
).
ready
(
function
(){
initTable
();
$
(
".select2"
).
select2
();
})
.
on
(
'click'
,
'.labels li'
,
function
()
{
var
val
=
$
(
this
).
text
();
{
#
var
origin_val
=
$
(
"#asset_list_table_filter input"
).
val
();
#
}
{
#
var
new_val
;
#
}
{
#
if
(
origin_val
===
""
)
{
#
}
{
#
new_val
=
val
;
#
}
{
#
}
else
{
#
}
{
#
new_val
=
origin_val
+
" "
+
val
;
#
}
{
#
}
#
}
$
(
"#asset_list_table_filter input"
).
val
(
val
);
{
#
$
(
'#asset_list_table'
).
DataTable
().
search
(
val
).
draw
();
#
}
jumpserver
.
table
.
search
(
val
).
draw
();
})
.
on
(
'click'
,
'.btn_export'
,
function
()
{
var
$data_table
=
$
(
'#asset_list_table'
).
DataTable
();
...
...
apps/assets/utils.py
View file @
cb902362
# ~*~ coding: utf-8 ~*~
#
from
collections
import
defaultdict
from
functools
import
reduce
import
operator
from
django.db.models
import
Q
from
common.utils
import
get_object_or_none
from
.models
import
Asset
,
SystemUser
from
.models
import
Asset
,
SystemUser
,
Label
def
get_assets_by_id_list
(
id_list
):
...
...
@@ -27,3 +32,23 @@ def check_assets_have_system_user(assets, system_users):
if
asset
.
cluster
not
in
clusters
:
errors
[
asset
]
.
append
(
system_user
)
return
errors
class
LabelFilter
:
def
filter_queryset
(
self
,
queryset
):
query_keys
=
self
.
request
.
query_params
.
keys
()
all_label_keys
=
Label
.
objects
.
values_list
(
'name'
,
flat
=
True
)
valid_keys
=
set
(
all_label_keys
)
&
set
(
query_keys
)
labels_query
=
{}
for
key
in
valid_keys
:
labels_query
[
key
]
=
self
.
request
.
query_params
.
get
(
key
)
conditions
=
[]
for
k
,
v
in
labels_query
.
items
():
query
=
{
'labels__name'
:
k
,
'labels__value'
:
v
}
conditions
.
append
(
query
)
if
conditions
:
for
kwargs
in
conditions
:
queryset
=
queryset
.
filter
(
**
kwargs
)
return
queryset
apps/assets/views/asset.py
View file @
cb902362
...
...
@@ -27,7 +27,7 @@ from common.mixins import JSONResponseMixin
from
common.utils
import
get_object_or_none
,
get_logger
,
is_uuid
from
common.const
import
create_success_msg
,
update_success_msg
from
..
import
forms
from
..models
import
Asset
,
AssetGroup
,
AdminUser
,
Cluster
,
SystemUser
from
..models
import
Asset
,
AssetGroup
,
AdminUser
,
Cluster
,
SystemUser
,
Label
from
..hands
import
AdminUserRequiredMixin
...
...
@@ -48,6 +48,7 @@ class AssetListView(AdminUserRequiredMixin, TemplateView):
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Asset list'
),
'system_users'
:
SystemUser
.
objects
.
all
(),
'labels'
:
Label
.
objects
.
all
()
.
order_by
(
'name'
),
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
...
...
@@ -72,12 +73,13 @@ class AssetCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateView):
template_name
=
'assets/asset_create.html'
success_url
=
reverse_lazy
(
'assets:asset-list'
)
def
form_valid
(
self
,
form
):
asset
=
form
.
save
()
asset
.
created_by
=
self
.
request
.
user
.
username
or
'Admin'
asset
.
date_created
=
timezone
.
now
()
asset
.
save
()
return
super
()
.
form_valid
(
form
)
# def form_valid(self, form):
# print("form valid")
# asset = form.save()
# asset.created_by = self.request.user.username or 'Admin'
# asset.date_created = timezone.now()
# asset.save()
# return super().form_valid(form)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
...
...
apps/static/css/jumpserver.css
View file @
cb902362
...
...
@@ -338,4 +338,6 @@ div.dataTables_wrapper div.dataTables_filter {
.nav.nav-tabs
li
.active
a
{
border
:
none
;
}
\ No newline at end of file
}
apps/static/js/jumpserver.js
View file @
cb902362
...
...
@@ -383,7 +383,22 @@ jumpserver.initServerSideDataTable = function (options) {
}
if
(
data
.
search
!==
null
)
{
var
search_val
=
data
.
search
.
value
;
data
.
search
=
search_val
;
var
search_list
=
search_val
.
split
(
" "
);
var
search_attr
=
{};
var
search_raw
=
[];
search_list
.
map
(
function
(
val
,
index
)
{
var
kv
=
val
.
split
(
":"
);
if
(
kv
.
length
===
2
)
{
search_attr
[
kv
[
0
]]
=
kv
[
1
]
}
else
{
search_raw
.
push
(
kv
)
}
});
data
.
search
=
search_raw
.
join
(
""
);
$
.
each
(
search_attr
,
function
(
k
,
v
)
{
data
[
k
]
=
v
})
}
if
(
data
.
order
!==
null
&&
data
.
order
.
length
===
1
)
{
var
col
=
data
.
order
[
0
].
column
;
...
...
@@ -446,6 +461,7 @@ jumpserver.initServerSideDataTable = function (options) {
}
});
jumpserver
.
table
=
table
;
return
table
;
};
...
...
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