Skip to content

Commit

Permalink
fix: 优化结构代码 TencentBlueKing#7626
Browse files Browse the repository at this point in the history
  • Loading branch information
guohelu committed Dec 12, 2024
1 parent 964f072 commit 7ad80c0
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 106 deletions.
2 changes: 0 additions & 2 deletions config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -890,5 +890,3 @@ def check_engine_admin_permission(request, *args, **kwargs):
ENABLE_TEMPLATE_MARKET = env.ENABLE_TEMPLATE_MARKET
# 流程商店 API 地址
TEMPLATE_MARKET_API_URL = env.TEMPLATE_MARKET_API_URL
# 共享流程最大数量
MAX_NUMBER_SHARED_PROCESSES = env.MAX_NUMBER_SHARED_PROCESSES
2 changes: 0 additions & 2 deletions env.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,5 +158,3 @@
ENABLE_TEMPLATE_MARKET = False if os.getenv("ENABLE_TEMPLATE_MARKET") is None else True
# 流程商店 API 地址
TEMPLATE_MARKET_API_URL = os.getenv("TEMPLATE_MARKET_API_URL", "")
# 共享流程最大数量
MAX_NUMBER_SHARED_PROCESSES = int(os.getenv("MAX_NUMBER_SHARED_PROCESSES", 10))
6 changes: 3 additions & 3 deletions gcloud/apigw/management/commands/data/api-resources.yml
Original file line number Diff line number Diff line change
Expand Up @@ -762,13 +762,13 @@ paths:
operationId: copy_template_across_project
description: 跨业务复制模板
tags:
- 通用接口
- 限制接口
responses:
default:
description: ''
x-bk-apigateway-resource:
isPublic: false
allowApplyPermission: true
isPublic: true
allowApplyPermission: false
matchSubpath: false
backend:
type: HTTP
Expand Down
2 changes: 1 addition & 1 deletion gcloud/apigw/views/copy_template_across_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def copy_template_across_project(request, project_id):
operator=request.user.username,
)
except Exception as e:
logger.exception("The process fails to be replicated across services: {}".format(e))
logger.exception("The template fails to be copied across project: {}".format(e))
return {
"result": False,
"message": "invalid flow data or error occur, please contact administrator",
Expand Down
4 changes: 2 additions & 2 deletions gcloud/contrib/template_market/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@

@admin.register(models.TemplateSharedRecord)
class TemplateSharedRecordAdmin(admin.ModelAdmin):
list_display = ["scene_shared_id", "project_id", "templates", "creator", "create_at", "update_at", "extra_info"]
list_display = ["market_record_id", "project_id", "templates", "creator", "create_at", "update_at", "extra_info"]
list_filter = ["project_id", "creator", "create_at", "update_at"]
search_fields = ["scene_shared_id", "project_id", "creator"]
search_fields = ["market_record_id", "project_id", "creator"]
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ def __init__(self):
def _get_url(self, endpoint):
return f"{self.base_url}{endpoint}"

def get_template_list(self):
url = self._get_url("/sre_scene/flow_template_scene/")
def get_market_template_list(self):
url = self._get_url("/sre_scene/flow_template_scene/?is_all=true")
response = requests.get(url)
return response.json()

def create_template(self, data):
def create_market_template_record(self, data):
url = self._get_url("/sre_scene/flow_template_scene/")
response = requests.post(url, json=data)
return response.json()

def patch_template(self, data, scene_shared_id):
url = self._get_url(f"/sre_scene/flow_template_scene/{scene_shared_id}/")
def patch_market_template_record(self, data, market_record_id):
url = self._get_url(f"/sre_scene/flow_template_scene/{market_record_id}/")
response = requests.patch(url, json=data)
return response.json()
6 changes: 3 additions & 3 deletions gcloud/contrib/template_market/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 3.2.15 on 2024-12-11 13:46
# Generated by Django 3.2.15 on 2024-12-12 09:15

from django.db import migrations, models

Expand All @@ -14,8 +14,8 @@ class Migration(migrations.Migration):
name="TemplateSharedRecord",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("scene_shared_id", models.IntegerField(help_text="共享实例id", verbose_name="共享实例id")),
("project_id", models.IntegerField(default=-1, help_text="项目 ID", verbose_name="项目 ID")),
("market_record_id", models.CharField(db_index=True, max_length=32, verbose_name="模板市场记录 ID")),
("project_id", models.IntegerField(help_text="项目 ID", verbose_name="项目 ID")),
("templates", models.JSONField(help_text="模板 ID 列表", verbose_name="模板 ID 列表")),
("creator", models.CharField(default="", max_length=32, verbose_name="创建者")),
("create_at", models.DateTimeField(auto_now_add=True, verbose_name="创建时间")),
Expand Down
2 changes: 1 addition & 1 deletion gcloud/contrib/template_market/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


class TemplateSharedRecord(models.Model):
scene_shared_id = models.IntegerField(_("共享实例id"), help_text="共享实例id")
market_record_id = models.CharField(_("共享实例 ID"), max_length=32, help_text="共享实例 ID", db_index=True)
project_id = models.IntegerField(_("项目 ID"), default=-1, help_text="项目 ID")
templates = models.JSONField(_("模板 ID 列表"), help_text="模板 ID 列表")
creator = models.CharField(_("创建者"), max_length=32, default="")
Expand Down
33 changes: 18 additions & 15 deletions gcloud/contrib/template_market/permission.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,24 @@
"""
import logging

from django.db.models import Q
from iam.exceptions import MultiAuthFailedException
from rest_framework import permissions

from gcloud.conf import settings
from gcloud.contrib.template_market.models import TemplateSharedRecord
from gcloud.contrib.template_market.serializers import TemplateProjectBaseSerializer
from gcloud.iam_auth import IAMMeta
from gcloud.iam_auth.utils import iam_multi_resource_auth_or_raise


class TemplatePreviewPermission(permissions.BasePermission):
def has_permission(self, request, view):
try:
template_id = int(request.GET.get("template_id"))
project_id = int(request.GET.get("project_id"))
except (TypeError, ValueError):
logging.warning("Missing or invalid required parameters.")
return False
serializer = TemplateProjectBaseSerializer(data=request.GET)
serializer.is_valid(raise_exception=True)

record = TemplateSharedRecord.objects.filter(
Q(project_id=project_id) & Q(templates__contains=[template_id])
).first()
template_id = int(serializer.validated_data["template_id"])
project_id = int(serializer.validated_data["project_id"])
record = TemplateSharedRecord.objects.filter(project_id=project_id, templates__contains=[template_id]).first()
if record is None:
logging.warning("The specified template could not be found")
return False
Expand All @@ -42,15 +39,21 @@ def has_permission(self, request, view):

class SharedProcessTemplatePermission(permissions.BasePermission):
def has_permission(self, request, view):
if not settings.ENABLE_TEMPLATE_MARKET:
return False

if view.action in ["create", "partial_update"]:
username = request.user.username
serializer = view.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)

template_id_list = serializer.validated_data["templates"]
try:
iam_multi_resource_auth_or_raise(
username, IAMMeta.FLOW_EDIT_ACTION, template_id_list, "resources_list_for_flows"
)
except MultiAuthFailedException:
logging.exception("You do not have permission to perform this operation")
return False

iam_multi_resource_auth_or_raise(
username, IAMMeta.FLOW_EDIT_ACTION, template_id_list, "resources_list_for_flows"
)

return settings.ENABLE_TEMPLATE_MARKET
return True
5 changes: 0 additions & 5 deletions gcloud/contrib/template_market/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import json
from rest_framework import serializers

from gcloud.constants import DATETIME_FORMAT
from gcloud.contrib.template_market.models import TemplateSharedRecord


Expand All @@ -34,8 +33,6 @@ class TemplateSharedRecordSerializer(serializers.ModelSerializer):
project_id = serializers.CharField(required=True, max_length=32, help_text="项目id")
templates = serializers.ListField(required=True, help_text="关联的模板列表")
creator = serializers.CharField(required=True, max_length=32, help_text="创建者")
create_at = serializers.DateTimeField(required=False, help_text="创建时间", format=DATETIME_FORMAT)
update_at = serializers.DateTimeField(required=False, help_text="更新时间", format=DATETIME_FORMAT)
extra_info = serializers.JSONField(required=False, allow_null=True, help_text="额外信息")
name = serializers.CharField(required=True, help_text="共享名称")
code = serializers.CharField(required=True, help_text="共享标识")
Expand All @@ -51,8 +48,6 @@ class Meta:
"project_id",
"templates",
"creator",
"create_at",
"update_at",
"extra_info",
"name",
"code",
Expand Down
92 changes: 25 additions & 67 deletions gcloud/contrib/template_market/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from rest_framework import permissions

from gcloud import err_code
from gcloud.conf import settings
from drf_yasg.utils import swagger_auto_schema
from gcloud.contrib.template_market.serializers import (
TemplateSharedRecordSerializer,
Expand All @@ -27,7 +26,7 @@
)
from gcloud.contrib.template_market.models import TemplateSharedRecord
from gcloud.taskflow3.models import TaskTemplate
from gcloud.contrib.template_market.utils import MarketAPIClient
from gcloud.contrib.template_market.clients import MarketAPIClient
from gcloud.contrib.template_market.permission import TemplatePreviewPermission, SharedProcessTemplatePermission


Expand Down Expand Up @@ -78,96 +77,55 @@ def _build_template_data(self, serializer, **kwargs):
data["id"] = scene_shared_id
return data

def _get_processes_count(self, template_id_list):
template_objs = TaskTemplate.objects.filter(id__in=template_id_list)

total_count = 0
for template in template_objs:
activities = template.pipeline_tree.get("activities", [])
total_count += len(activities)

return total_count

def list(self, request, *args, **kwargs):
response_data = self.market_client.get_template_list()
response_data = self.market_client.get_market_template_list()

if not response_data["result"]:
logging.exception(f"Get template information from market failed, error code: {response_data.get('code')}")
logging.exception("Failed to obtain the market template list")
return Response(
{"result": False, "message": "Get template information failed", "code": err_code.OPERATION_FAIL.code}
{
"result": False,
"message": "Failed to obtain the market template list",
"code": err_code.OPERATION_FAIL.code,
}
)

return Response({"result": True, "data": response_data, "code": err_code.SUCCESS.code})

@swagger_auto_schema(request_body=TemplateSharedRecordSerializer)
def create(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)

template_count = self._get_processes_count(serializer.validated_data["templates"])
if template_count > settings.MAX_NUMBER_SHARED_PROCESSES:
data = self._build_template_data(serializer)
response_data = self.market_client.create_market_template_record(data)
if not response_data.get("result"):
return Response(
{
"result": False,
"message": "The number of selected templates exceeds the limit",
"message": "Failed to create market template record",
"code": err_code.OPERATION_FAIL.code,
}
)

data = self._build_template_data(serializer)
try:
response_data = self.market_client.create_template(data)
if not response_data.get("result"):
return Response(
{
"result": False,
"message": "Failed to share template to sre store",
"code": err_code.OPERATION_FAIL.code,
}
)
serializer.validated_data["scene_shared_id"] = response_data["data"]["id"]
serializer.save()
return Response(
{
"result": True,
"data": "response_data",
"message": "Share template successfully",
"code": err_code.SUCCESS.code,
}
)
except Exception as e:
logging.exception("Share template failed: %s", e)
return Response({"result": False, "message": "Share template failed", "code": err_code.OPERATION_FAIL.code})
serializer.validated_data["market_record_id"] = response_data["data"]["id"]
serializer.create(serializer.validated_data)
return Response({"result": True, "data": response_data, "code": err_code.SUCCESS.code})

@swagger_auto_schema(request_body=TemplateSharedRecordSerializer)
def partial_update(self, request, *args, **kwargs):
scene_shared_id = kwargs["pk"]
instance = self.queryset.get(scene_shared_id=scene_shared_id)
market_record_id = kwargs["pk"]
instance = self.queryset.get(market_record_id=market_record_id)
serializer = self.serializer_class(data=request.data, partial=True)
serializer.is_valid(raise_exception=True)

data = self._build_template_data(serializer, scene_shared_id=scene_shared_id)
try:
response_data = self.market_client.patch_template(data, scene_shared_id)
if not response_data.get("result"):
return Response(
{
"result": False,
"message": "Update template to sre store failed",
"code": err_code.OPERATION_FAIL.code,
}
)
serializer.update(instance, validated_data=serializer.validated_data)
data = self._build_template_data(serializer, market_record_id=market_record_id)
response_data = self.market_client.patch_market_template_record(data, market_record_id)
if not response_data.get("result"):
return Response(
{
"result": True,
"data": response_data,
"message": "Share template successfully",
"code": err_code.SUCCESS.code,
"result": False,
"message": "Failed to update market template record",
"code": err_code.OPERATION_FAIL.code,
}
)
except Exception as e:
logging.exception("Failed to update scene template: %s", e)
return Response(
{"result": False, "message": "Failed to update scene template", "code": err_code.OPERATION_FAIL.code}
)
serializer.update(instance=instance, validated_data=serializer.validated_data)
return Response({"result": True, "data": response_data, "code": err_code.SUCCESS.code})

0 comments on commit 7ad80c0

Please sign in to comment.