From 6d7c478bfcf497dacafa6555a226e735e914beec Mon Sep 17 00:00:00 2001 From: Innokentii Konstantinov Date: Wed, 8 Jun 2022 12:23:24 +0400 Subject: [PATCH 1/2] Add periodic task to sync users with cloud --- engine/apps/oss_installation/tasks.py | 16 +++++++++++++++- engine/settings/all_in_one.py | 7 ++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/engine/apps/oss_installation/tasks.py b/engine/apps/oss_installation/tasks.py index 2c11a54a..2bb54991 100644 --- a/engine/apps/oss_installation/tasks.py +++ b/engine/apps/oss_installation/tasks.py @@ -7,7 +7,7 @@ from django.utils import timezone from rest_framework import status from apps.base.utils import live_settings -from apps.oss_installation.models import CloudHeartbeat, OssInstallation +from apps.oss_installation.models import CloudConnector, CloudHeartbeat, OssInstallation from apps.oss_installation.usage_stats import UsageStatsService from common.custom_celery_tasks import shared_dedicated_queue_retry_task @@ -93,3 +93,17 @@ def send_cloud_heartbeat(): if cloud_heartbeat.pk is not None: cloud_heartbeat.save() logger.info("Finish send cloud heartbeat") + + +@shared_dedicated_queue_retry_task() +def sync_users_with_cloud(): + logger.info("Start sync_users_with_cloud") + connector = CloudConnector.objects.first() + if connector is not None: + status, error = connector.sync_users_with_cloud() + log_message = "Users synced. Status {status}." + if error: + log_message += f" Error {error}" + logger.info(log_message) + else: + logger.info("Grafana Cloud is not connected") diff --git a/engine/settings/all_in_one.py b/engine/settings/all_in_one.py index e2196274..221edd52 100644 --- a/engine/settings/all_in_one.py +++ b/engine/settings/all_in_one.py @@ -40,6 +40,7 @@ if TESTING: # TODO: OSS: Add these setting to oss settings file. Add Version there too. OSS_INSTALLATION_FEATURES_ENABLED = True +SEND_ANONYMOUS_USAGE_STATS = True INSTALLED_APPS += ["apps.oss_installation"] # noqa @@ -55,4 +56,8 @@ CELERY_BEAT_SCHEDULE["send_cloud_heartbeat"] = { # noqa "args": (), } # noqa -SEND_ANONYMOUS_USAGE_STATS = True +CELERY_BEAT_SCHEDULE["sync_users_with_cloud"] = { # noqa + "task": "apps.oss_installation.tasks.sync_users_with_cloud", + "schedule": crontab(hour="*/12"), # noqa + "args": (), +} # noqa From 893da302e146da12512c2b51d0db2bdf25f79046 Mon Sep 17 00:00:00 2001 From: Innokentii Konstantinov Date: Wed, 8 Jun 2022 15:04:23 +0400 Subject: [PATCH 2/2] Fix cloud_users view --- .../oss_installation/serializers/cloud_user.py | 2 +- engine/apps/oss_installation/urls.py | 17 ++++++----------- .../apps/oss_installation/views/cloud_users.py | 10 +++++++--- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/engine/apps/oss_installation/serializers/cloud_user.py b/engine/apps/oss_installation/serializers/cloud_user.py index d8e35791..52f2d0e0 100644 --- a/engine/apps/oss_installation/serializers/cloud_user.py +++ b/engine/apps/oss_installation/serializers/cloud_user.py @@ -12,7 +12,7 @@ class CloudUserSerializer(serializers.ModelSerializer): class Meta: model = User - fields = ["sync_data"] + fields = ["cloud_data"] def get_cloud_data(self, obj): link = None diff --git a/engine/apps/oss_installation/urls.py b/engine/apps/oss_installation/urls.py index 25708249..9ff5efc2 100644 --- a/engine/apps/oss_installation/urls.py +++ b/engine/apps/oss_installation/urls.py @@ -1,19 +1,14 @@ -from django.urls import path +from django.urls import include, path -from common.api_helpers.optional_slash_router import optional_slash_path +from common.api_helpers.optional_slash_router import OptionalSlashRouter, optional_slash_path from .views import CloudConnectionView, CloudUsersView, CloudUserView +router = OptionalSlashRouter() +router.register("cloud_users", CloudUserView, basename="cloud-users") + urlpatterns = [ + path("", include(router.urls)), optional_slash_path("cloud_users", CloudUsersView.as_view(), name="cloud-users-list"), - path( - "cloud_users/", - CloudUserView.as_view( - { - "get": "retrieve", - } - ), - name="cloud-user-detail", - ), optional_slash_path("cloud_connection", CloudConnectionView.as_view(), name="cloud-connection-status"), ] diff --git a/engine/apps/oss_installation/views/cloud_users.py b/engine/apps/oss_installation/views/cloud_users.py index ab28c677..5f6cc67f 100644 --- a/engine/apps/oss_installation/views/cloud_users.py +++ b/engine/apps/oss_installation/views/cloud_users.py @@ -7,7 +7,7 @@ from rest_framework.response import Response from rest_framework.views import APIView import apps.oss_installation.constants as cloud_constants -from apps.api.permissions import ActionPermission, IsAdmin, IsOwnerOrAdmin +from apps.api.permissions import ActionPermission, AnyRole, IsAdmin, IsOwnerOrAdmin from apps.auth_token.auth import PluginAuthentication from apps.oss_installation.models import CloudConnector, CloudUserIdentity from apps.oss_installation.serializers import CloudUserSerializer @@ -81,8 +81,12 @@ class CloudUserView( authentication_classes = (PluginAuthentication,) permission_classes = (IsAuthenticated, ActionPermission) + action_permissions = { + AnyRole: ("retrieve",), + IsAdmin: ("sync",), + } action_object_permissions = { - IsOwnerOrAdmin: ("retrieve",), + IsOwnerOrAdmin: ("retrieve", "sync"), } serializer_class = CloudUserSerializer @@ -91,7 +95,7 @@ class CloudUserView( return queryset @action(detail=True, methods=["post"]) - def sync_with_cloud(self, request, pk): + def sync(self, request, pk): user = self.get_object() connector = CloudConnector.objects.first() if connector is not None: