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
b95f8a7d
Unverified
Commit
b95f8a7d
authored
Dec 17, 2018
by
老广
Committed by
GitHub
Dec 17, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 修复获取节点数量比较慢的问题 (#2184)
parent
985bd6fc
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
83 additions
and
45 deletions
+83
-45
node.py
apps/assets/api/node.py
+1
-2
node.py
apps/assets/models/node.py
+52
-27
node.py
apps/assets/serializers/node.py
+5
-13
signals_handler.py
apps/assets/signals_handler.py
+17
-3
_asset_list_modal.html
apps/assets/templates/assets/_asset_list_modal.html
+1
-0
asset_list.html
apps/assets/templates/assets/asset_list.html
+7
-0
No files found.
apps/assets/api/node.py
View file @
b95f8a7d
...
@@ -20,11 +20,10 @@ from rest_framework.response import Response
...
@@ -20,11 +20,10 @@ from rest_framework.response import Response
from
rest_framework_bulk
import
BulkModelViewSet
from
rest_framework_bulk
import
BulkModelViewSet
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.shortcuts
import
get_object_or_404
from
django.shortcuts
import
get_object_or_404
from
django.db.models
import
Count
from
common.utils
import
get_logger
,
get_object_or_none
from
common.utils
import
get_logger
,
get_object_or_none
from
..hands
import
IsOrgAdmin
from
..hands
import
IsOrgAdmin
from
..models
import
Node
from
..models
import
Node
,
Asset
from
..tasks
import
update_assets_hardware_info_util
,
test_asset_connectability_util
from
..tasks
import
update_assets_hardware_info_util
,
test_asset_connectability_util
from
..
import
serializers
from
..
import
serializers
...
...
apps/assets/models/node.py
View file @
b95f8a7d
...
@@ -22,7 +22,9 @@ class Node(OrgModelMixin):
...
@@ -22,7 +22,9 @@ class Node(OrgModelMixin):
date_create
=
models
.
DateTimeField
(
auto_now_add
=
True
)
date_create
=
models
.
DateTimeField
(
auto_now_add
=
True
)
is_node
=
True
is_node
=
True
_full_value_cache_key_prefix
=
'_NODE_VALUE_{}'
_assets_amount
=
None
_full_value_cache_key
=
'_NODE_VALUE_{}'
_assets_amount_cache_key
=
'_NODE_ASSETS_AMOUNT_{}'
class
Meta
:
class
Meta
:
verbose_name
=
_
(
"Node"
)
verbose_name
=
_
(
"Node"
)
...
@@ -49,30 +51,56 @@ class Node(OrgModelMixin):
...
@@ -49,30 +51,56 @@ class Node(OrgModelMixin):
def
name
(
self
):
def
name
(
self
):
return
self
.
value
return
self
.
value
@property
def
assets_amount
(
self
):
"""
获取节点下所有资产数量速度太慢,所以需要重写,使用cache等方案
:return:
"""
if
self
.
_assets_amount
is
not
None
:
return
self
.
_assets_amount
cache_key
=
self
.
_assets_amount_cache_key
.
format
(
self
.
key
)
cached
=
cache
.
get
(
cache_key
)
if
cached
is
not
None
:
return
cached
assets_amount
=
self
.
get_all_assets
()
.
count
()
cache
.
set
(
cache_key
,
assets_amount
,
3600
)
return
assets_amount
@assets_amount.setter
def
assets_amount
(
self
,
value
):
self
.
_assets_amount
=
value
def
expire_assets_amount
(
self
):
ancestor_keys
=
self
.
get_ancestor_keys
(
with_self
=
True
)
cache_keys
=
[
self
.
_assets_amount_cache_key
.
format
(
k
)
for
k
in
ancestor_keys
]
cache
.
delete_many
(
cache_keys
)
@classmethod
def
expire_nodes_assets_amount
(
cls
,
nodes
=
None
):
if
nodes
:
for
node
in
nodes
:
node
.
expire_assets_amount
()
return
key
=
cls
.
_assets_amount_cache_key
.
format
(
'*'
)
cache
.
delete_pattern
(
key
)
@property
@property
def
full_value
(
self
):
def
full_value
(
self
):
key
=
self
.
_full_value_cache_key
_prefix
.
format
(
self
.
key
)
key
=
self
.
_full_value_cache_key
.
format
(
self
.
key
)
cached
=
cache
.
get
(
key
)
cached
=
cache
.
get
(
key
)
if
cached
:
if
cached
:
return
cached
return
cached
value
=
self
.
get_full_value
()
self
.
cache_full_value
(
value
)
return
value
def
get_full_value
(
self
):
# ancestor = [a.value for a in self.get_ancestor(with_self=True)]
if
self
.
is_root
():
if
self
.
is_root
():
return
self
.
value
return
self
.
value
parent_full_value
=
self
.
parent
.
full_value
parent_full_value
=
self
.
parent
.
full_value
value
=
parent_full_value
+
' / '
+
self
.
value
value
=
parent_full_value
+
' / '
+
self
.
value
return
value
key
=
self
.
_full_value_cache_key
.
format
(
self
.
key
)
def
cache_full_value
(
self
,
value
):
key
=
self
.
_full_value_cache_key_prefix
.
format
(
self
.
key
)
cache
.
set
(
key
,
value
,
3600
)
cache
.
set
(
key
,
value
,
3600
)
return
value
def
expire_full_value
(
self
):
def
expire_full_value
(
self
):
key
=
self
.
_full_value_cache_key
_prefix
.
format
(
self
.
key
)
key
=
self
.
_full_value_cache_key
.
format
(
self
.
key
)
cache
.
delete_pattern
(
key
+
'*'
)
cache
.
delete_pattern
(
key
+
'*'
)
@property
@property
...
@@ -182,17 +210,18 @@ class Node(OrgModelMixin):
...
@@ -182,17 +210,18 @@ class Node(OrgModelMixin):
child
.
save
()
child
.
save
()
self
.
save
()
self
.
save
()
def
get_ancestor
(
self
,
with_self
=
False
):
def
get_ancestor_keys
(
self
,
with_self
=
False
):
if
self
.
is_root
():
parent_keys
=
[]
root
=
self
.
__class__
.
root
()
key_list
=
self
.
key
.
split
(
":"
)
return
[
root
]
_key
=
self
.
key
.
split
(
':'
)
if
not
with_self
:
if
not
with_self
:
_key
.
pop
()
key_list
.
pop
()
ancestor_keys
=
[]
for
i
in
range
(
len
(
key_list
)):
for
i
in
range
(
len
(
_key
)):
parent_keys
.
append
(
":"
.
join
(
key_list
))
ancestor_keys
.
append
(
':'
.
join
(
_key
))
key_list
.
pop
()
_key
.
pop
()
return
parent_keys
def
get_ancestor
(
self
,
with_self
=
False
):
ancestor_keys
=
self
.
get_ancestor_keys
(
with_self
=
with_self
)
ancestor
=
self
.
__class__
.
objects
.
filter
(
ancestor
=
self
.
__class__
.
objects
.
filter
(
key__in
=
ancestor_keys
key__in
=
ancestor_keys
)
.
order_by
(
'key'
)
)
.
order_by
(
'key'
)
...
@@ -227,10 +256,6 @@ class Node(OrgModelMixin):
...
@@ -227,10 +256,6 @@ class Node(OrgModelMixin):
defaults
=
{
'value'
:
'Default'
}
defaults
=
{
'value'
:
'Default'
}
return
cls
.
objects
.
get_or_create
(
defaults
=
defaults
,
key
=
'1'
)
return
cls
.
objects
.
get_or_create
(
defaults
=
defaults
,
key
=
'1'
)
@classmethod
def
get_tree_name_ref
(
cls
):
pass
@classmethod
@classmethod
def
generate_fake
(
cls
,
count
=
100
):
def
generate_fake
(
cls
,
count
=
100
):
import
random
import
random
...
...
apps/assets/serializers/node.py
View file @
b95f8a7d
...
@@ -43,7 +43,7 @@ class NodeGrantedSerializer(BulkSerializerMixin, serializers.ModelSerializer):
...
@@ -43,7 +43,7 @@ class NodeGrantedSerializer(BulkSerializerMixin, serializers.ModelSerializer):
class
NodeSerializer
(
serializers
.
ModelSerializer
):
class
NodeSerializer
(
serializers
.
ModelSerializer
):
assets_amount
=
serializers
.
SerializerMethod
Field
()
assets_amount
=
serializers
.
Integer
Field
()
tree_id
=
serializers
.
SerializerMethodField
()
tree_id
=
serializers
.
SerializerMethodField
()
tree_parent
=
serializers
.
SerializerMethodField
()
tree_parent
=
serializers
.
SerializerMethodField
()
...
@@ -53,6 +53,10 @@ class NodeSerializer(serializers.ModelSerializer):
...
@@ -53,6 +53,10 @@ class NodeSerializer(serializers.ModelSerializer):
'id'
,
'key'
,
'value'
,
'assets_amount'
,
'id'
,
'key'
,
'value'
,
'assets_amount'
,
'is_node'
,
'org_id'
,
'tree_id'
,
'tree_parent'
,
'is_node'
,
'org_id'
,
'tree_id'
,
'tree_parent'
,
]
]
read_only_fields
=
[
'id'
,
'key'
,
'assets_amount'
,
'is_node'
,
'org_id'
,
]
list_serializer_class
=
BulkListSerializer
list_serializer_class
=
BulkListSerializer
def
validate
(
self
,
data
):
def
validate
(
self
,
data
):
...
@@ -66,12 +70,6 @@ class NodeSerializer(serializers.ModelSerializer):
...
@@ -66,12 +70,6 @@ class NodeSerializer(serializers.ModelSerializer):
)
)
return
data
return
data
@staticmethod
def
get_assets_amount
(
obj
):
if
hasattr
(
obj
,
'assets_amount'
):
return
obj
.
assets_amount
return
obj
.
get_all_assets
()
.
count
()
@staticmethod
@staticmethod
def
get_tree_id
(
obj
):
def
get_tree_id
(
obj
):
return
obj
.
key
return
obj
.
key
...
@@ -80,12 +78,6 @@ class NodeSerializer(serializers.ModelSerializer):
...
@@ -80,12 +78,6 @@ class NodeSerializer(serializers.ModelSerializer):
def
get_tree_parent
(
obj
):
def
get_tree_parent
(
obj
):
return
obj
.
parent_key
return
obj
.
parent_key
def
get_fields
(
self
):
fields
=
super
()
.
get_fields
()
field
=
fields
[
"key"
]
field
.
required
=
False
return
fields
class
NodeAssetsSerializer
(
serializers
.
ModelSerializer
):
class
NodeAssetsSerializer
(
serializers
.
ModelSerializer
):
assets
=
serializers
.
PrimaryKeyRelatedField
(
many
=
True
,
queryset
=
Asset
.
objects
.
all
())
assets
=
serializers
.
PrimaryKeyRelatedField
(
many
=
True
,
queryset
=
Asset
.
objects
.
all
())
...
...
apps/assets/signals_handler.py
View file @
b95f8a7d
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
from
collections
import
defaultdict
from
collections
import
defaultdict
from
django.db.models.signals
import
post_save
,
m2m_changed
from
django.db.models.signals
import
post_save
,
m2m_changed
,
post_delete
from
django.dispatch
import
receiver
from
django.dispatch
import
receiver
from
common.utils
import
get_logger
from
common.utils
import
get_logger
...
@@ -35,6 +35,17 @@ def on_asset_created_or_update(sender, instance=None, created=False, **kwargs):
...
@@ -35,6 +35,17 @@ def on_asset_created_or_update(sender, instance=None, created=False, **kwargs):
update_asset_hardware_info_on_created
(
instance
)
update_asset_hardware_info_on_created
(
instance
)
test_asset_conn_on_created
(
instance
)
test_asset_conn_on_created
(
instance
)
# 过期节点资产数量
nodes
=
instance
.
nodes
.
all
()
Node
.
expire_nodes_assets_amount
(
nodes
)
@receiver
(
post_delete
,
sender
=
Asset
,
dispatch_uid
=
"my_unique_identifier"
)
def
on_asset_delete
(
sender
,
instance
=
None
,
**
kwargs
):
# 过期节点资产数量
nodes
=
instance
.
nodes
.
all
()
Node
.
expire_nodes_assets_amount
(
nodes
)
@receiver
(
post_save
,
sender
=
SystemUser
,
dispatch_uid
=
"my_unique_identifier"
)
@receiver
(
post_save
,
sender
=
SystemUser
,
dispatch_uid
=
"my_unique_identifier"
)
def
on_system_user_update
(
sender
,
instance
=
None
,
created
=
True
,
**
kwargs
):
def
on_system_user_update
(
sender
,
instance
=
None
,
created
=
True
,
**
kwargs
):
...
@@ -63,10 +74,11 @@ def on_system_user_assets_change(sender, instance=None, **kwargs):
...
@@ -63,10 +74,11 @@ def on_system_user_assets_change(sender, instance=None, **kwargs):
@receiver
(
m2m_changed
,
sender
=
Asset
.
nodes
.
through
)
@receiver
(
m2m_changed
,
sender
=
Asset
.
nodes
.
through
)
def
on_asset_node_changed
(
sender
,
instance
=
None
,
**
kwargs
):
def
on_asset_node_changed
(
sender
,
instance
=
None
,
**
kwargs
):
logger
.
debug
(
"Asset node change signal received"
)
if
isinstance
(
instance
,
Asset
):
if
isinstance
(
instance
,
Asset
):
if
kwargs
[
'action'
]
==
'post_add'
:
if
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Asset node change signal received"
)
nodes
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
nodes
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
Node
.
expire_nodes_assets_amount
(
nodes
)
system_users_assets
=
defaultdict
(
set
)
system_users_assets
=
defaultdict
(
set
)
system_users
=
SystemUser
.
objects
.
filter
(
nodes__in
=
nodes
)
system_users
=
SystemUser
.
objects
.
filter
(
nodes__in
=
nodes
)
# 清理节点缓存
# 清理节点缓存
...
@@ -79,9 +91,11 @@ def on_asset_node_changed(sender, instance=None, **kwargs):
...
@@ -79,9 +91,11 @@ def on_asset_node_changed(sender, instance=None, **kwargs):
@receiver
(
m2m_changed
,
sender
=
Asset
.
nodes
.
through
)
@receiver
(
m2m_changed
,
sender
=
Asset
.
nodes
.
through
)
def
on_node_assets_changed
(
sender
,
instance
=
None
,
**
kwargs
):
def
on_node_assets_changed
(
sender
,
instance
=
None
,
**
kwargs
):
if
isinstance
(
instance
,
Node
):
if
isinstance
(
instance
,
Node
):
logger
.
debug
(
"Node assets change signal received"
)
# 当节点和资产关系发生改变时,过期资产数量缓存
instance
.
expire_assets_amount
()
assets
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
assets
=
kwargs
[
'model'
]
.
objects
.
filter
(
pk__in
=
kwargs
[
'pk_set'
])
if
kwargs
[
'action'
]
==
'post_add'
:
if
kwargs
[
'action'
]
==
'post_add'
:
logger
.
debug
(
"Node assets change signal received"
)
# 重新关联系统用户和资产的关系
# 重新关联系统用户和资产的关系
system_users
=
SystemUser
.
objects
.
filter
(
nodes
=
instance
)
system_users
=
SystemUser
.
objects
.
filter
(
nodes
=
instance
)
for
system_user
in
system_users
:
for
system_user
in
system_users
:
...
...
apps/assets/templates/assets/_asset_list_modal.html
View file @
b95f8a7d
...
@@ -116,6 +116,7 @@ function initTree2() {
...
@@ -116,6 +116,7 @@ function initTree2() {
$
(
document
).
ready
(
function
(){
$
(
document
).
ready
(
function
(){
}).
on
(
'show.bs.modal'
,
function
()
{
initTable2
();
initTable2
();
initTree2
();
initTree2
();
})
})
...
...
apps/assets/templates/assets/asset_list.html
View file @
b95f8a7d
...
@@ -305,6 +305,9 @@ function onSelected(event, treeNode) {
...
@@ -305,6 +305,9 @@ function onSelected(event, treeNode) {
}
}
function
selectQueryNode
()
{
function
selectQueryNode
()
{
// TODO: 是否应该添加
// 暂时忽略之前选中的内容
return
var
query_node_id
=
$
.
getUrlParam
(
"node"
);
var
query_node_id
=
$
.
getUrlParam
(
"node"
);
var
cookie_node_id
=
getCookie
(
'node_selected'
);
var
cookie_node_id
=
getCookie
(
'node_selected'
);
var
node
;
var
node
;
...
@@ -355,6 +358,9 @@ function onDrop(event, treeId, treeNodes, targetNode, moveType) {
...
@@ -355,6 +358,9 @@ function onDrop(event, treeId, treeNodes, targetNode, moveType) {
}
}
function
initTree
()
{
function
initTree
()
{
if
(
zTree
)
{
return
}
var
setting
=
{
var
setting
=
{
view
:
{
view
:
{
dblClickExpand
:
false
,
dblClickExpand
:
false
,
...
@@ -387,6 +393,7 @@ function initTree() {
...
@@ -387,6 +393,7 @@ function initTree() {
};
};
var
zNodes
=
[];
var
zNodes
=
[];
console
.
log
(
"Get assets"
)
$
.
get
(
"{% url 'api-assets:node-list' %}"
,
function
(
data
,
status
){
$
.
get
(
"{% url 'api-assets:node-list' %}"
,
function
(
data
,
status
){
$
.
each
(
data
,
function
(
index
,
value
)
{
$
.
each
(
data
,
function
(
index
,
value
)
{
value
[
"node_id"
]
=
value
[
"id"
];
value
[
"node_id"
]
=
value
[
"id"
];
...
...
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