Skip to content

feat(plugin): 接入标准运维开放插件运行时与治理能力#698

Open
dengyh wants to merge 8 commits intoTencentBlueKing:masterfrom
dengyh:feat/sops-open-plugin-backend
Open

feat(plugin): 接入标准运维开放插件运行时与治理能力#698
dengyh wants to merge 8 commits intoTencentBlueKing:masterfrom
dengyh:feat/sops-open-plugin-backend

Conversation

@dengyh
Copy link
Copy Markdown
Collaborator

@dengyh dengyh commented Apr 21, 2026

Summary

  • 接入 uniform_api v4.0.0,补齐标准运维开放插件目录索引、空间治理、回调鉴权与任务运行时接入
  • 新增开放插件快照、版本状态回填与 plugin_source 统计维度扩展
  • 同步更新 APIGW 资源定义、中文文档与测试脚本环境兜底

Test Plan

  • pytest -o addopts='' tests/plugins/uniform_api/test_uniform_api_client.py tests/plugins/components/collections/uniform_api_test tests/interface/plugin/services/test_plugin_schema_service.py tests/interface/space/test_space_views.py tests/interface/apigw/test_list_plugins.py tests/interface/apigw/test_get_plugin_schema.py tests/interface/apigw/test_operate_task.py tests/interface/apigw/test_operate_task_node.py -q
  • pytest -o addopts='' tests/interface/statistics tests/engine/statistics -q
  • git diff --check -- bkflow tests scripts

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

大体量 PR,整体架构合理——uniform_api v4.0.0 协议扩展、开放插件目录索引 + 空间治理、回调鉴权与快照体系都方向正确,文档与 APIGW 资源同步也已覆盖。以下几点值得关注:

需要修复

  1. create_taskcollect_plugin_references 被重复调用 3 次(validate → build_reference → build_schema),每次内部都有 N+1 查询。建议抽取为一次调用,传递结果给后续方法。
  2. collect_plugin_references 存在 N+1 查询——循环内逐条查 OpenPluginCatalogIndexSpaceOpenPluginAvailability,在任务创建/模板保存等 API 路径上会放大。建议批量预取。
  3. 📄 backfill_open_plugin_snapshots.py 缺少开源协议头,项目规范要求每个新增 Python 文件顶部包含 MIT 许可声明。

建议优化

  1. enable_all_visible_plugins 循环调用 update_or_create,可改为 bulk_create + update 提升批量开启效率。
  2. _refresh_catalog_index 的循环 update_or_create 在低频同步场景可接受,若后续插件量增长可考虑批量化。
  3. SpaceViewSet 新增 4 个 open_plugin action,当前继承的 AdminPermission | SpaceSuperuserPermission | SpaceExemptionPermission 足够(空间管理功能),确认符合预期。

username=request.user.username,
scope_type=template.scope_type,
scope_id=template.scope_value,
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validate_pipeline_treebuild_reference_snapshotbuild_schema_snapshot 各自内部都调用了 collect_plugin_references,等于同一棵 pipeline_tree 被扫描了 3 遍且每次都有 N+1 查询。建议改为调用一次 collect_plugin_references,将结果传给后续方法复用。

if not plugin_id:
continue

catalog = cls._get_catalog_entry(space_id=space_id, plugin_id=plugin_id, source_key=source_key)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚡ 循环内逐条调用 _get_catalog_entry(ORM query)和 SpaceOpenPluginAvailability.objects.filter().exists(),对于含多个开放插件节点的 pipeline 会产生 2N 次查询。建议在循环前批量 filter(plugin_id__in=...) 预取 catalog 和 availability map。

@@ -0,0 +1,89 @@
from django.core.management.base import BaseCommand
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📄 缺少项目要求的开源协议头(MIT License),其他新增 .py 文件如 open_plugin_callback.pyopen_plugin_catalog.py 等都已包含。请补齐。

catalog_qs = catalog_qs.filter(source_key=source_key)

updated = []
for item in catalog_qs.only("source_key", "plugin_id"):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚡ 循环内调用 toggle_plugin(即 update_or_create),若空间内可用插件较多(如 100+)会产生 200+ 次查询。建议改为先 filter().update(enabled=True) 批量更新存在的记录,再 bulk_create 缺失记录。

@return_json_response
def operate_task_node(request, space_id, task_id, node_id, operation):
data = json.loads(request.body)
if _is_open_plugin_callback_request(operation, data):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 开放插件回调分支在 Serializer 校验之前拦截,绕过了 OperateTaskNodeSerializer 的参数校验。当前 _handle_open_plugin_callback 内部有完整的 token 验签 + 字段提取逻辑,但 data["open_plugin_run_id"] 在第 81 行直接作为查询条件使用而未做格式校验——建议至少校验其非空且为合法字符串。

@classmethod
def get_snapshot_node_statuses(cls, space_id, extra_info):
statuses = {}
for ref in cls.get_reference_snapshot(extra_info):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚡ 与 collect_plugin_references 类似,get_snapshot_node_statuses 也在循环内逐条查 catalog + availability。若此方法会在高频路径上被调用,同样建议批量预取。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant