diff --git a/apps/jumpserver/api.py b/apps/jumpserver/api.py index 0f0193c49..4e734bda6 100644 --- a/apps/jumpserver/api.py +++ b/apps/jumpserver/api.py @@ -18,6 +18,7 @@ from terminal.utils import ComponentsPrometheusMetricsUtil from orgs.utils import current_org from common.permissions import IsOrgAdmin, IsOrgAuditor from common.utils import lazyproperty +from orgs.caches import OrgResourceStatisticsCache __all__ = ['IndexApi'] @@ -210,26 +211,7 @@ class DatesLoginMetricMixin: return sessions -class TotalCountMixin: - @staticmethod - def get_total_count_users(): - return current_org.get_members().count() - - @staticmethod - def get_total_count_assets(): - return Asset.objects.all().count() - - @staticmethod - def get_total_count_online_users(): - count = len(set(Session.objects.filter(is_finished=False).values_list('user_id', flat=True))) - return count - - @staticmethod - def get_total_count_online_sessions(): - return Session.objects.filter(is_finished=False).count() - - -class IndexApi(TotalCountMixin, DatesLoginMetricMixin, APIView): +class IndexApi(DatesLoginMetricMixin, APIView): permission_classes = (IsOrgAdmin | IsOrgAuditor,) http_method_names = ['get'] @@ -238,26 +220,28 @@ class IndexApi(TotalCountMixin, DatesLoginMetricMixin, APIView): query_params = self.request.query_params + caches = OrgResourceStatisticsCache(self.request.user.user_orgs[0]) + _all = query_params.get('all') if _all or query_params.get('total_count') or query_params.get('total_count_users'): data.update({ - 'total_count_users': self.get_total_count_users(), + 'total_count_users': caches.users_amount, }) if _all or query_params.get('total_count') or query_params.get('total_count_assets'): data.update({ - 'total_count_assets': self.get_total_count_assets(), + 'total_count_assets': caches.assets_amount, }) if _all or query_params.get('total_count') or query_params.get('total_count_online_users'): data.update({ - 'total_count_online_users': self.get_total_count_online_users(), + 'total_count_online_users': caches.total_count_online_users, }) if _all or query_params.get('total_count') or query_params.get('total_count_online_sessions'): data.update({ - 'total_count_online_sessions': self.get_total_count_online_sessions(), + 'total_count_online_sessions': caches.total_count_online_sessions, }) if _all or query_params.get('dates_metrics'): diff --git a/apps/orgs/caches.py b/apps/orgs/caches.py index 9c29659e4..c9d60bd18 100644 --- a/apps/orgs/caches.py +++ b/apps/orgs/caches.py @@ -6,12 +6,12 @@ from orgs.utils import current_org, tmp_to_org from common.cache import Cache, IntegerField from common.utils import get_logger from users.models import UserGroup, User -from assets.models import Node, AdminUser, SystemUser, Domain, Gateway +from assets.models import Node, AdminUser, SystemUser, Domain, Gateway, Asset +from terminal.models import Session from applications.models import Application from perms.models import AssetPermission, ApplicationPermission from .models import OrganizationMember - logger = get_logger(__file__) @@ -64,6 +64,9 @@ class OrgResourceStatisticsCache(OrgRelatedCache): asset_perms_amount = IntegerField(queryset=AssetPermission.objects) app_perms_amount = IntegerField(queryset=ApplicationPermission.objects) + total_count_online_users = IntegerField() + total_count_online_sessions = IntegerField() + def __init__(self, org): super().__init__() self.org = org @@ -86,3 +89,9 @@ class OrgResourceStatisticsCache(OrgRelatedCache): def compute_assets_amount(self): node = Node.org_root() return node.assets_amount + + def compute_total_count_online_users(self): + return len(set(Session.objects.filter(is_finished=False).values_list('user_id', flat=True))) + + def compute_total_count_online_sessions(self): + return Session.objects.filter(is_finished=False).count() diff --git a/apps/orgs/signals_handler/cache.py b/apps/orgs/signals_handler/cache.py index c3c23efb4..5862d5edf 100644 --- a/apps/orgs/signals_handler/cache.py +++ b/apps/orgs/signals_handler/cache.py @@ -1,5 +1,5 @@ from django.db.models.signals import m2m_changed -from django.db.models.signals import post_save, pre_delete +from django.db.models.signals import post_save, pre_delete, pre_save from django.dispatch import receiver from orgs.models import Organization, OrganizationMember @@ -7,6 +7,7 @@ from assets.models import Node from perms.models import (AssetPermission, ApplicationPermission) from users.models import UserGroup, User from applications.models import Application +from terminal.models import Session from assets.models import Asset, AdminUser, SystemUser, Domain, Gateway from common.const.signals import POST_PREFIX from orgs.caches import OrgResourceStatisticsCache @@ -47,16 +48,17 @@ def on_org_user_changed_refresh_cache(sender, action, instance, reverse, pk_set, class OrgResourceStatisticsRefreshUtil: model_cache_field_mapper = { - ApplicationPermission: 'app_perms_amount', - AssetPermission: 'asset_perms_amount', - Application: 'applications_amount', - Gateway: 'gateways_amount', - Domain: 'domains_amount', - SystemUser: 'system_users_amount', - AdminUser: 'admin_users_amount', - Node: 'nodes_amount', - Asset: 'assets_amount', - UserGroup: 'groups_amount', + ApplicationPermission: ['app_perms_amount'], + AssetPermission: ['asset_perms_amount'], + Application: ['applications_amount'], + Gateway: ['gateways_amount'], + Domain: ['domains_amount'], + SystemUser: ['system_users_amount'], + AdminUser: ['admin_users_amount'], + Node: ['nodes_amount'], + Asset: ['assets_amount'], + UserGroup: ['groups_amount'], + Session: ['total_count_online_users', 'total_count_online_sessions'] } @classmethod @@ -64,13 +66,12 @@ class OrgResourceStatisticsRefreshUtil: cache_field_name = cls.model_cache_field_mapper.get(type(instance)) if cache_field_name: org_cache = OrgResourceStatisticsCache(instance.org) - org_cache.expire(cache_field_name) + org_cache.expire(*cache_field_name) -@receiver(post_save) -def on_post_save_refresh_org_resource_statistics_cache(sender, instance, created, **kwargs): - if created: - OrgResourceStatisticsRefreshUtil.refresh_if_need(instance) +@receiver(pre_save) +def on_post_save_refresh_org_resource_statistics_cache(sender, instance, **kwargs): + OrgResourceStatisticsRefreshUtil.refresh_if_need(instance) @receiver(pre_delete)