mirror of https://github.com/jumpserver/jumpserver
[update] 修改一些性能问题
parent
218e425333
commit
1472f0437f
|
@ -149,9 +149,10 @@ class AssetUserTestConnectiveApi(generics.RetrieveAPIView):
|
||||||
def get_asset_users(self):
|
def get_asset_users(self):
|
||||||
username = self.request.GET.get('username')
|
username = self.request.GET.get('username')
|
||||||
asset_id = self.request.GET.get('asset_id')
|
asset_id = self.request.GET.get('asset_id')
|
||||||
|
prefer = self.request.GET.get("prefer")
|
||||||
asset = get_object_or_none(Asset, pk=asset_id)
|
asset = get_object_or_none(Asset, pk=asset_id)
|
||||||
manager = AssetUserManager()
|
manager = AssetUserManager()
|
||||||
asset_users = manager.filter(username=username, assets=[asset])
|
asset_users = manager.filter(username=username, assets=[asset], prefer=prefer)
|
||||||
return asset_users
|
return asset_users
|
||||||
|
|
||||||
def retrieve(self, request, *args, **kwargs):
|
def retrieve(self, request, *args, **kwargs):
|
||||||
|
|
|
@ -126,6 +126,7 @@ class Asset(OrgModelMixin):
|
||||||
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
|
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment'))
|
||||||
|
|
||||||
objects = OrgManager.from_queryset(AssetQuerySet)()
|
objects = OrgManager.from_queryset(AssetQuerySet)()
|
||||||
|
_connectivity = None
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{0.hostname}({0.ip})'.format(self)
|
return '{0.hostname}({0.ip})'.format(self)
|
||||||
|
@ -221,17 +222,18 @@ class Asset(OrgModelMixin):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def connectivity(self):
|
def connectivity(self):
|
||||||
|
if self._connectivity:
|
||||||
|
return self._connectivity
|
||||||
if not self.admin_user:
|
if not self.admin_user:
|
||||||
return Connectivity.unknown()
|
return Connectivity.unknown()
|
||||||
instance = self.admin_user.get_asset_user(self)
|
connectivity = self.admin_user.get_asset_connectivity(self)
|
||||||
return instance.connectivity
|
return connectivity
|
||||||
|
|
||||||
@connectivity.setter
|
@connectivity.setter
|
||||||
def connectivity(self, value):
|
def connectivity(self, value):
|
||||||
if not self.admin_user:
|
if not self.admin_user:
|
||||||
return
|
return
|
||||||
instance = self.admin_user.get_asset_user(self)
|
self.admin_user.set_asset_connectivity(self, value)
|
||||||
instance.set_asset_connectivity(self, value)
|
|
||||||
|
|
||||||
def get_auth_info(self):
|
def get_auth_info(self):
|
||||||
if not self.admin_user:
|
if not self.admin_user:
|
||||||
|
|
|
@ -35,8 +35,8 @@ class AssetUser(OrgModelMixin):
|
||||||
date_updated = models.DateTimeField(auto_now=True, verbose_name=_("Date updated"))
|
date_updated = models.DateTimeField(auto_now=True, verbose_name=_("Date updated"))
|
||||||
created_by = models.CharField(max_length=128, null=True, verbose_name=_('Created by'))
|
created_by = models.CharField(max_length=128, null=True, verbose_name=_('Created by'))
|
||||||
|
|
||||||
CONNECTIVITY_ASSET_CACHE_KEY = "ASSET_USER_{}_ASSET_CONNECTIVITY"
|
CONNECTIVITY_ASSET_CACHE_KEY = "ASSET_USER_{}_{}_ASSET_CONNECTIVITY"
|
||||||
CONNECTIVITY_AMOUNT_CACHE_KEY = "ASSET_USER_{}_CONNECTIVITY_AMOUNT"
|
CONNECTIVITY_AMOUNT_CACHE_KEY = "ASSET_USER_{}_{}_CONNECTIVITY_AMOUNT"
|
||||||
ASSETS_AMOUNT_CACHE_KEY = "ASSET_USER_{}_ASSETS_AMOUNT"
|
ASSETS_AMOUNT_CACHE_KEY = "ASSET_USER_{}_ASSETS_AMOUNT"
|
||||||
ASSET_USER_CACHE_TIME = 3600 * 24
|
ASSET_USER_CACHE_TIME = 3600 * 24
|
||||||
|
|
||||||
|
@ -99,21 +99,24 @@ class AssetUser(OrgModelMixin):
|
||||||
unreachable = summary.get('dark', {}).keys()
|
unreachable = summary.get('dark', {}).keys()
|
||||||
reachable = summary.get('contacted', {}).keys()
|
reachable = summary.get('contacted', {}).keys()
|
||||||
|
|
||||||
for asset in self.get_related_assets():
|
assets = self.get_related_assets()
|
||||||
|
if not isinstance(assets, list):
|
||||||
|
assets = assets.only('id', 'hostname', 'admin_user__id')
|
||||||
|
for asset in assets:
|
||||||
if asset.hostname in unreachable:
|
if asset.hostname in unreachable:
|
||||||
self.set_asset_connectivity(asset, Connectivity.unreachable())
|
self.set_asset_connectivity(asset, Connectivity.unreachable())
|
||||||
elif asset.hostname in reachable:
|
elif asset.hostname in reachable:
|
||||||
self.set_asset_connectivity(asset, Connectivity.reachable())
|
self.set_asset_connectivity(asset, Connectivity.reachable())
|
||||||
else:
|
else:
|
||||||
self.set_asset_connectivity(asset, Connectivity.unknown())
|
self.set_asset_connectivity(asset, Connectivity.unknown())
|
||||||
cache_key = self.CONNECTIVITY_AMOUNT_CACHE_KEY.format(self.part_id)
|
cache_key = self.CONNECTIVITY_AMOUNT_CACHE_KEY.format(self.username, self.part_id)
|
||||||
cache.delete(cache_key)
|
cache.delete(cache_key)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def connectivity(self):
|
def connectivity(self):
|
||||||
assets = self.get_related_assets()\
|
assets = self.get_related_assets()
|
||||||
.select_related('admin_user')\
|
if not isinstance(assets, list):
|
||||||
.only('id', 'hostname', 'admin_user')
|
assets = assets.only('id', 'hostname', 'admin_user__id')
|
||||||
data = {
|
data = {
|
||||||
'unreachable': [],
|
'unreachable': [],
|
||||||
'reachable': [],
|
'reachable': [],
|
||||||
|
@ -131,11 +134,11 @@ class AssetUser(OrgModelMixin):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def connectivity_amount(self):
|
def connectivity_amount(self):
|
||||||
cache_key = self.CONNECTIVITY_AMOUNT_CACHE_KEY.format(self.part_id)
|
cache_key = self.CONNECTIVITY_AMOUNT_CACHE_KEY.format(self.username, self.part_id)
|
||||||
amount = cache.get(cache_key)
|
amount = cache.get(cache_key)
|
||||||
if not amount:
|
if not amount:
|
||||||
connectivity = {k: len(v) for k, v in self.connectivity.items()}
|
amount = {k: len(v) for k, v in self.connectivity.items()}
|
||||||
cache.set(cache_key, connectivity, self.ASSET_USER_CACHE_TIME)
|
cache.set(cache_key, amount, self.ASSET_USER_CACHE_TIME)
|
||||||
return amount
|
return amount
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -152,17 +155,18 @@ class AssetUser(OrgModelMixin):
|
||||||
cache.delete(cache_key)
|
cache.delete(cache_key)
|
||||||
|
|
||||||
def get_asset_connectivity(self, asset):
|
def get_asset_connectivity(self, asset):
|
||||||
i = self.generate_id_with_asset(asset)
|
key = self.get_asset_connectivity_key(asset)
|
||||||
key = self.CONNECTIVITY_ASSET_CACHE_KEY.format(i)
|
|
||||||
return Connectivity.get(key)
|
return Connectivity.get(key)
|
||||||
|
|
||||||
|
def get_asset_connectivity_key(self, asset):
|
||||||
|
return self.CONNECTIVITY_ASSET_CACHE_KEY.format(self.username, asset.id)
|
||||||
|
|
||||||
def set_asset_connectivity(self, asset, c):
|
def set_asset_connectivity(self, asset, c):
|
||||||
i = self.generate_id_with_asset(asset)
|
key = self.get_asset_connectivity_key(asset)
|
||||||
key = self.CONNECTIVITY_ASSET_CACHE_KEY.format(i)
|
|
||||||
Connectivity.set(key, c)
|
Connectivity.set(key, c)
|
||||||
# 当为某个系统用户或管理用户设置的的时候,失效掉他们的连接数量
|
# 当为某个系统用户或管理用户设置的的时候,失效掉他们的连接数量
|
||||||
amount_key = self.CONNECTIVITY_AMOUNT_CACHE_KEY.format(self.part_id)
|
amount_key = self.CONNECTIVITY_AMOUNT_CACHE_KEY.format(self.username, '*')
|
||||||
cache.delete(amount_key)
|
cache.delete_pattern(amount_key)
|
||||||
|
|
||||||
def get_asset_user(self, asset):
|
def get_asset_user(self, asset):
|
||||||
from ..backends import AssetUserManager
|
from ..backends import AssetUserManager
|
||||||
|
|
|
@ -98,5 +98,11 @@ class Connectivity:
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.status == other.status
|
return self.status == other.status
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
return self.status > other.status
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
return not self.__gt__(other)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.display()
|
return self.display()
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
#
|
#
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.validators import ValidationError
|
from rest_framework.validators import ValidationError
|
||||||
|
from django.db.models import Prefetch
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orgs.mixins import BulkOrgResourceModelSerializer
|
from orgs.mixins import BulkOrgResourceModelSerializer
|
||||||
from common.serializers import AdaptedBulkListSerializer
|
from common.serializers import AdaptedBulkListSerializer
|
||||||
from ..models import Asset, Protocol
|
from ..models import Asset, Protocol, Node, Label
|
||||||
from .base import ConnectivitySerializer
|
from .base import ConnectivitySerializer
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
@ -58,7 +58,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer):
|
||||||
'cpu_model', 'cpu_count', 'cpu_cores', 'cpu_vcpus', 'memory',
|
'cpu_model', 'cpu_count', 'cpu_cores', 'cpu_vcpus', 'memory',
|
||||||
'disk_total', 'disk_info', 'os', 'os_version', 'os_arch',
|
'disk_total', 'disk_info', 'os', 'os_version', 'os_arch',
|
||||||
'hostname_raw', 'comment', 'created_by', 'date_created',
|
'hostname_raw', 'comment', 'created_by', 'date_created',
|
||||||
'hardware_info', 'connectivity'
|
'hardware_info', 'connectivity',
|
||||||
]
|
]
|
||||||
read_only_fields = (
|
read_only_fields = (
|
||||||
'vendor', 'model', 'sn', 'cpu_model', 'cpu_count',
|
'vendor', 'model', 'sn', 'cpu_model', 'cpu_count',
|
||||||
|
@ -76,8 +76,11 @@ class AssetSerializer(BulkOrgResourceModelSerializer):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup_eager_loading(cls, queryset):
|
def setup_eager_loading(cls, queryset):
|
||||||
""" Perform necessary eager loading of data. """
|
""" Perform necessary eager loading of data. """
|
||||||
queryset = queryset.prefetch_related('labels', 'nodes', 'protocols')\
|
queryset = queryset.prefetch_related(
|
||||||
.select_related('admin_user', 'domain')
|
Prefetch('nodes', queryset=Node.objects.all().only('id')),
|
||||||
|
Prefetch('labels', queryset=Label.objects.all().only('id')),
|
||||||
|
'protocols'
|
||||||
|
).select_related('admin_user', 'domain')
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -576,6 +576,7 @@ def test_asset_user_connectivity_util(asset_user, task_name, run_as_admin=False)
|
||||||
|
|
||||||
tasks = get_test_asset_user_connectivity_tasks(asset_user.asset)
|
tasks = get_test_asset_user_connectivity_tasks(asset_user.asset)
|
||||||
if not tasks:
|
if not tasks:
|
||||||
|
logger.debug("No tasks ")
|
||||||
return
|
return
|
||||||
|
|
||||||
args = (task_name,)
|
args = (task_name,)
|
||||||
|
|
|
@ -92,8 +92,8 @@ function initAssetUserTable() {
|
||||||
ajax_url: assetUserListUrl,
|
ajax_url: assetUserListUrl,
|
||||||
columns: [
|
columns: [
|
||||||
{data: "id"}, {data: "hostname"}, {data: "ip"},
|
{data: "id"}, {data: "hostname"}, {data: "ip"},
|
||||||
{data: "username", orderable: false}, {data: "version", orderable: false},
|
{data: "username"}, {data: "version", orderable: false},
|
||||||
{data: "connectivity", orderable: false},
|
{data: "connectivity"},
|
||||||
{data: "date_created", orderable: false},
|
{data: "date_created", orderable: false},
|
||||||
{data: "asset", orderable: false}
|
{data: "asset", orderable: false}
|
||||||
],
|
],
|
||||||
|
|
|
@ -75,7 +75,7 @@ function initTable() {
|
||||||
}},
|
}},
|
||||||
{targets: 4, createdCell: function (td, cellData) {
|
{targets: 4, createdCell: function (td, cellData) {
|
||||||
var innerHtml = "";
|
var innerHtml = "";
|
||||||
var data = cellData['reachable'];
|
var data = cellData.reachable;
|
||||||
if (data !== 0) {
|
if (data !== 0) {
|
||||||
innerHtml = "<span class='text-navy'>" + data + "</span>";
|
innerHtml = "<span class='text-navy'>" + data + "</span>";
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -57,10 +57,15 @@ class JMSCSVRender(BaseRenderer):
|
||||||
request = renderer_context['request']
|
request = renderer_context['request']
|
||||||
template = request.query_params.get('template', 'export')
|
template = request.query_params.get('template', 'export')
|
||||||
view = renderer_context['view']
|
view = renderer_context['view']
|
||||||
data = json.loads(json.dumps(data, cls=encoders.JSONEncoder))
|
|
||||||
|
if isinstance(data, dict) and data.get("count"):
|
||||||
|
data = data["results"]
|
||||||
|
|
||||||
if template == 'import':
|
if template == 'import':
|
||||||
data = [data[0]] if data else data
|
data = [data[0]] if data else data
|
||||||
|
|
||||||
|
data = json.loads(json.dumps(data, cls=encoders.JSONEncoder))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
serializer = view.get_serializer()
|
serializer = view.get_serializer()
|
||||||
self.set_response_disposition(serializer, renderer_context)
|
self.set_response_disposition(serializer, renderer_context)
|
||||||
|
|
|
@ -47,7 +47,7 @@ def run_command_execution(cid, **kwargs):
|
||||||
try:
|
try:
|
||||||
execution.run()
|
execution.run()
|
||||||
except SoftTimeLimitExceeded:
|
except SoftTimeLimitExceeded:
|
||||||
print("HLLL")
|
logger.error("Run time out")
|
||||||
else:
|
else:
|
||||||
logger.error("Not found the execution id: {}".format(cid))
|
logger.error("Not found the execution id: {}".format(cid))
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,8 @@ class OrgModelViewSet(IDInCacheFilterMixin, ModelViewSet):
|
||||||
class OrgBulkModelViewSet(IDInCacheFilterMixin, BulkModelViewSet):
|
class OrgBulkModelViewSet(IDInCacheFilterMixin, BulkModelViewSet):
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
queryset = super().get_queryset().all()
|
queryset = super().get_queryset().all()
|
||||||
if hasattr(self, 'serializer_class') and \
|
if hasattr(self, 'action') and self.action == 'list' and \
|
||||||
|
hasattr(self, 'serializer_class') and \
|
||||||
hasattr(self.serializer_class, 'setup_eager_loading'):
|
hasattr(self.serializer_class, 'setup_eager_loading'):
|
||||||
queryset = self.serializer_class.setup_eager_loading(queryset)
|
queryset = self.serializer_class.setup_eager_loading(queryset)
|
||||||
return queryset
|
return queryset
|
||||||
|
|
|
@ -32,10 +32,10 @@ class OrgManager(models.Manager):
|
||||||
kwargs['org_id'] = _current_org.id
|
kwargs['org_id'] = _current_org.id
|
||||||
elif _current_org.is_default():
|
elif _current_org.is_default():
|
||||||
queryset = queryset.filter(org_id="")
|
queryset = queryset.filter(org_id="")
|
||||||
|
#
|
||||||
# lines = traceback.format_stack()
|
# lines = traceback.format_stack()
|
||||||
# print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
# print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>")
|
||||||
# for line in lines[-10:-5]:
|
# for line in lines[-10:-1]:
|
||||||
# print(line)
|
# print(line)
|
||||||
# print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
|
# print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
|
||||||
|
|
||||||
|
|
|
@ -262,7 +262,6 @@ class UserGrantedNodesWithAssetsAsTreeApi(UserPermissionCacheMixin, ListAPIView)
|
||||||
system_users=self.system_user_id
|
system_users=self.system_user_id
|
||||||
)
|
)
|
||||||
nodes = util.get_nodes_with_assets()
|
nodes = util.get_nodes_with_assets()
|
||||||
print(list(nodes.keys()))
|
|
||||||
for node, assets in nodes.items():
|
for node, assets in nodes.items():
|
||||||
data = parse_node_to_tree_node(node)
|
data = parse_node_to_tree_node(node)
|
||||||
queryset.append(data)
|
queryset.append(data)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">{% trans "Download the imported template or use the exported CSV file format" %}</label>
|
<label class="control-label">{% trans "Download the imported template or use the exported CSV file format" %}</label>
|
||||||
<a href="{% block import_modal_download_template_url %}{% endblock %}?format=csv&template=import" style="display: block">{% trans 'Download the import template' %}</a>
|
<a href="{% block import_modal_download_template_url %}{% endblock %}?format=csv&template=import&limit=1" style="display: block">{% trans 'Download the import template' %}</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
Loading…
Reference in New Issue