Skip to content

Commit

Permalink
feat: 流程市场共享模板查看 #7626
Browse files Browse the repository at this point in the history
  • Loading branch information
guohelu committed Dec 4, 2024
1 parent 6bb7d28 commit 747f95a
Show file tree
Hide file tree
Showing 17 changed files with 342 additions and 5 deletions.
7 changes: 7 additions & 0 deletions config/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"gcloud.contrib.develop",
"gcloud.contrib.collection",
"gcloud.contrib.operate_record",
"gcloud.contrib.templatemaker",
"gcloud.apigw",
"gcloud.common_template",
"gcloud.label",
Expand Down Expand Up @@ -883,3 +884,9 @@ def check_engine_admin_permission(request, *args, **kwargs):
if "BKAPP_SOPS_BROKER_URL" in os.environ:
BROKER_URL = os.getenv("BKAPP_SOPS_BROKER_URL")
print(f"BROKER_URL: {BROKER_URL}")


# 共享模板开关
ENABLE_FLOW_MARKET = env.ENABLE_FLOW_MARKET
# SRE 商店路由
FLOW_MARKET_API_URL = env.FLOW_MARKET_API_URL
10 changes: 5 additions & 5 deletions config/urls_custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
from django.conf.urls import include, url
from django.conf import settings

from django.conf.urls import include, url
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
from rest_framework import permissions

# 用户自定义 urlconf
urlpatterns_custom = [
Expand All @@ -41,6 +40,7 @@
url(r"^plugin_service/", include("plugin_service.urls")),
url(r"^mako_operations/", include("gcloud.mako_template_helper.urls")),
url(r"^engine_admin/", include("pipeline.contrib.engine_admin.urls")),
url(r"^template_maker/", include("gcloud.contrib.templatemaker.urls")),
]

schema_view = get_schema_view(
Expand Down
5 changes: 5 additions & 0 deletions env.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,8 @@
# bk_audit
BK_AUDIT_ENDPOINT = os.getenv("BK_AUDIT_ENDPOINT", None)
BK_AUDIT_DATA_TOKEN = os.getenv("BK_AUDIT_DATA_TOKEN", None)

# 共享模板开关
ENABLE_FLOW_MARKET = False if os.getenv("BKAPP_ENABLE_FLOW_MARKET") is None else True
# SRE 商店路由
FLOW_MARKET_API_URL = os.getenv("FLOW_MARKET_API_URL", "")
Empty file.
23 changes: 23 additions & 0 deletions gcloud/contrib/templatemaker/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""

from django.contrib import admin

from gcloud.contrib.templatemaker import models


@admin.register(models.TemplateSharedRecord)
class AppMakerAdmin(admin.ModelAdmin):
list_display = ["project_id", "template_id", "template_source", "create", "create_time"]
list_filter = ["project_id", "template_source", "create", "create_time"]
search_fields = ["project_id", "create"]
Empty file.
Empty file.
98 changes: 98 additions & 0 deletions gcloud/contrib/templatemaker/apis/django/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""
import json
import requests
import logging

from rest_framework.response import Response
from django.views.decorators.http import require_POST, require_GET
from django.http import JsonResponse

from gcloud.conf import settings
from gcloud import err_code
from gcloud.contrib.templatemaker.models import TemplateSharedRecord
from gcloud.tasktmpl3.models import TaskTemplate
from gcloud.utils.decorators import request_validate
from gcloud.contrib.templatemaker.apis.django.validators import JsonValidator


def _get_market_routing(market_url):
return "{}/{}".format(settings.FLOW_MARKET_API_URL, market_url)


@require_GET
def get_template_market_details(request, template_id):
project_id = json.loads(request.body).get("project_id")

url = _get_market_routing("market/details/")

kwargs = {
"project_id": project_id,
}

# 根据业务id和模板id从第三方接口获取模板详情
result = requests.post(url, data=kwargs)

if not result:
logging.exception("get market template details from third party fails")
return Response(
{
"result": False,
"message": "get market template details from third party fails",
"code": err_code.OPERATION_FAIL.code,
}
)

return True


@require_POST
@request_validate(JsonValidator)
def maker_template(request, template_id):
if not settings.ENABLE_FLOW_MARKET:
return False

params = json.loads(request.body)
project_id = params.get("project_id")
try:
TaskTemplate.objects.filter(id=template_id, project__id=project_id).first()
except Exception as e:
logging.exception(e)
return Response(
{"result": False, "message": "template_id does not exist", "code": err_code.OPERATION_FAIL.code}
)

url = _get_market_routing("prod/api/")

kwargs = None

headers = None

# 调用第三方接口
result = requests.post(url, headers=headers, data=kwargs)

if not result:
logging.exception("Sharing template to SRE store fails")
return JsonResponse(
{"result": False, "message": "Sharing template to SRE store fails", "code": err_code.OPERATION_FAIL.code}
)

record, created = TemplateSharedRecord.objects.get_or_create(
project_id=params["project_id"],
template_id=template_id,
defaults={"template_source": params["template_source"], "create": request.user.username},
)
if not created:
return JsonResponse({"result": False, "message": "Record already exists", "code": err_code.OPERATION_FAIL.code})

return JsonResponse({"result": True, "message": "shared success", "code": err_code.SUCCESS.code})
33 changes: 33 additions & 0 deletions gcloud/contrib/templatemaker/apis/django/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""

import logging
import ujson as json

from django.utils.translation import ugettext_lazy as _

from gcloud.utils.validate import RequestValidator

logger = logging.getLogger("root")


class JsonValidator(RequestValidator):
def validate(self, request, *args, **kwargs):
try:
json.loads(request.body)
except Exception:
message = _("非法请求: 数据错误, 请求不是合法的Json格式 | validate")
logger.error(message)
return False, message

return True, ""
Empty file.
14 changes: 14 additions & 0 deletions gcloud/contrib/templatemaker/apis/drf/viewsets/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""

from gcloud.contrib.templatemaker.apis.drf.viewsets.template_marker import TemplateMakerViewSet # noqa
57 changes: 57 additions & 0 deletions gcloud/contrib/templatemaker/apis/drf/viewsets/template_marker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""

import logging

from rest_framework.response import Response
from rest_framework import permissions

from gcloud.contrib.templatemaker.models import TemplateSharedRecord
from gcloud.core.apis.drf.serilaziers.task_template import TaskTemplateSerializer, TaskTemplateListSerializer
from gcloud.taskflow3.models import TaskTemplate
from gcloud.label.models import TemplateLabelRelation
from gcloud.core.apis.drf.viewsets.base import GcloudModelViewSet


class HasValidTemplateID(permissions.BasePermission):
def has_permission(self, request, view):
template_id = view.kwargs.get("pk")

if not template_id:
logging.warning("template_id is required.")
return False
try:
TemplateSharedRecord.objects.get(template_id=template_id)
except Exception:
logging.warning("template_id {} does not exist.".format(template_id))
return False
return True


class TemplateMakerViewSet(GcloudModelViewSet):
queryset = TaskTemplate.objects.filter(pipeline_template__isnull=False, is_deleted=False)
permission_classes = [permissions.IsAuthenticated, HasValidTemplateID]

def get_serializer_class(self):
if self.action == "list":
return TaskTemplateListSerializer
return TaskTemplateSerializer

def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
data = serializer.data
labels = TemplateLabelRelation.objects.fetch_templates_labels([instance.id]).get(instance.id, [])
data["template_labels"] = [label["label_id"] for label in labels]

return Response(data)
6 changes: 6 additions & 0 deletions gcloud/contrib/templatemaker/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class TemplatemakerConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "gcloud.contrib.templatemaker"
37 changes: 37 additions & 0 deletions gcloud/contrib/templatemaker/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Generated by Django 3.2.15 on 2024-12-04 10:14

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="TemplateSharedRecord",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("project_id", models.IntegerField(default=-1, help_text="项目 ID", verbose_name="项目 ID")),
("template_id", models.IntegerField(db_index=True, verbose_name="模版ID")),
(
"template_source",
models.CharField(
choices=[("project", "项目流程"), ("common", "公共流程"), ("onetime", "一次性任务")],
default="project",
max_length=32,
verbose_name="流程模板来源",
),
),
("create", models.CharField(help_text="执行者", max_length=128, verbose_name="执行者")),
("create_time", models.DateTimeField(auto_now_add=True, help_text="执行时间", verbose_name="执行时间")),
],
options={
"verbose_name": "模板共享记录 TemplateSharedRecord",
"verbose_name_plural": "模板共享记录 TemplateSharedRecord",
"unique_together": {("project_id", "template_id")},
},
),
]
Empty file.
31 changes: 31 additions & 0 deletions gcloud/contrib/templatemaker/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""


from django.db import models
from django.utils.translation import ugettext_lazy as _

from gcloud.constants import TEMPLATE_SOURCE, PROJECT


class TemplateSharedRecord(models.Model):
project_id = models.IntegerField(_("项目 ID"), default=-1, help_text="项目 ID")
template_id = models.IntegerField(_("模版ID"), db_index=True)
template_source = models.CharField(_("流程模板来源"), max_length=32, choices=TEMPLATE_SOURCE, default=PROJECT)
create = models.CharField(_("执行者"), max_length=128, help_text="执行者")
create_time = models.DateTimeField(_("执行时间"), auto_now_add=True, help_text="执行时间")

class Meta:
verbose_name = _("模板共享记录 TemplateSharedRecord")
verbose_name_plural = _("模板共享记录 TemplateSharedRecord")
unique_together = ("project_id", "template_id")
26 changes: 26 additions & 0 deletions gcloud/contrib/templatemaker/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""

from django.conf.urls import include, url
from rest_framework.routers import DefaultRouter
from gcloud.contrib.templatemaker.apis.drf.viewsets import TemplateMakerViewSet
from gcloud.contrib.templatemaker.apis.django import api

drf_api = DefaultRouter()
drf_api.register(r"template", TemplateMakerViewSet)

urlpatterns = [
url(r"^api/maker/", include(drf_api.urls)),
url(r"^api/process_maker/(?P<template_id>\d+)/", api.maker_template),
url(r"^api/template_detail/(?P<template_id>\d+)/", api.get_template_market_details),
]

0 comments on commit 747f95a

Please sign in to comment.