Skip to content

Commit f9b6218

Browse files
committed
docs: add documentation and schema updates for APISIX 3.16 support
- Add JSON schema validation documentation - Update APISIX 3.16 plugin schemas - Include various documentation files for development workflow
1 parent 14b859c commit f9b6218

85 files changed

Lines changed: 21158 additions & 2133 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apisix-prod-v1-schema.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

bk-plugin-jsonschema-check.md

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
# BK 插件 JSON Schema 检查
2+
3+
## 2026-06-09 更新
4+
5+
已按 `src/dashboard/apigateway/apigateway/fixtures/plugins.yaml` 中的 dashboard 插件配置补齐 operator 的 3.13 / 3.16 JSON schema。当前 dashboard 暴露的 16 个 `bk-*` 插件在两份 schema 中都能找到 `plugins.<name>.schema`,不会再落入“缺失 schema 的 `bk-*` 插件直接跳过校验”的分支。
6+
7+
本次补齐的 7 个插件:
8+
9+
```text
10+
bk-status-rewrite
11+
bk-oauth2-protected-resource
12+
bk-oauth2-verify
13+
bk-oauth2-audience-validate
14+
bk-username-required
15+
bk-legacy-invalid-params
16+
bk-traffic-label
17+
```
18+
19+
说明:下文保留了初始排查时对远端 `blueking-apigateway-apisix` 全量 `bk-*` 插件的背景分析。远端仍有一些非 dashboard 配置入口的内部插件未纳入 operator schema;本次修复范围是 dashboard `plugins.yaml` 暴露的可配置插件。
20+
21+
## 结论
22+
23+
是的,operator 对 `bk-*` 插件有特殊逻辑:当插件名以 `bk-` 开头,并且在当前 APISIX 版本的 JSON schema 中找不到该插件 schema 时,operator 会跳过该插件配置校验。
24+
25+
因此,`src/operator/pkg/utils/schema/3.13/schema.json``src/operator/pkg/utils/schema/3.16/schema.json` 里只有 9 个 `bk-*` 插件 schema,并不代表 dashboard 只能发布这 9 个插件。operator 仍然会校验 route/service/plugin_metadata 等主资源结构,但对缺失 schema 的 `bk-*` 插件配置本身不做 JSON schema 校验。
26+
27+
## 关键代码证据
28+
29+
### 1. `bk-*` 被定义为内部插件
30+
31+
`src/operator/pkg/utils/schema/schema.go`:
32+
33+
```go
34+
func IsInnerPlugin(pluginName string) bool {
35+
return strings.HasPrefix(pluginName, "bk-")
36+
}
37+
```
38+
39+
### 2. 插件 schema 查找逻辑
40+
41+
`src/operator/pkg/utils/schema/schema.go`:
42+
43+
```go
44+
func GetPluginSchema(version constant.APISIXVersion, name, schemaType string) any {
45+
var ret any
46+
if schemaType == "consumer" || schemaType == "consumer_schema" {
47+
ret = schemaVersionMap[version].Get("plugins." + name + ".consumer_schema").Value()
48+
}
49+
if schemaType == "metadata" || schemaType == "metadata_schema" {
50+
return GetMetadataPluginSchema(version, "plugins."+name+".metadata_schema")
51+
}
52+
if schemaType == "stream" || schemaType == "stream_schema" {
53+
return schemaVersionMap[version].Get("stream_plugins." + name + ".schema").Value()
54+
}
55+
if ret == nil {
56+
ret = schemaVersionMap[version].Get("plugins." + name + ".schema").Value()
57+
}
58+
return ret
59+
}
60+
```
61+
62+
### 3. 缺失 schema 的 `bk-*` 插件会被跳过
63+
64+
`src/operator/pkg/utils/schema/validate.go`:
65+
66+
```go
67+
schemaValue := GetPluginSchema(v.version, pluginName, schemaType)
68+
if schemaValue == nil && v.customizePluginSchemaMap != nil {
69+
schemaValue = v.customizePluginSchemaMap[pluginName]
70+
}
71+
// 如果是内置插件,且找不到schema,直接跳过校验
72+
if IsInnerPlugin(pluginName) && schemaValue == nil {
73+
continue
74+
}
75+
if schemaValue == nil {
76+
return fmt.Errorf("资源:%s schema 验证失败: 未找到 schema, 路径: %s",
77+
resourceIdentification, "plugins."+pluginName)
78+
}
79+
```
80+
81+
含义:
82+
83+
-`bk-*` 插件:找不到 schema 会报错。
84+
- `bk-*` 插件:找不到 schema 会 `continue`,即跳过该插件配置校验。
85+
- 如果 `bk-*` 插件在 schema.json 里有条目,则仍然会校验该插件配置。
86+
87+
## 校验链路
88+
89+
operator 从 APIGW 控制面 etcd 读取 APISIX 原生资源后,会进入 schema 校验:
90+
91+
- `src/operator/pkg/core/registry/apigw.go`
92+
- `ValueToStageResource()` 对 stage 资源调用 `ValidateApisixJsonSchema(...)`
93+
- `ValueToGlobalResource()` 对 global `plugin_metadata` 资源调用 `ValidateApisixJsonSchema(...)`
94+
- `src/operator/pkg/core/validator/validator.go`
95+
- `ValidateApisixJsonSchema()` 根据资源 label 中的 APISIX 版本选择 `3.13.X``3.16.X` schema
96+
- `src/operator/pkg/utils/schema/validate.go`
97+
- 先校验资源主 schema
98+
- 再逐个校验 plugins
99+
- 对缺失 schema 的 `bk-*` 插件跳过插件配置校验
100+
101+
所以不是“完全不校验包含 bk 插件的资源”,而是:
102+
103+
1. route/service/plugin_metadata 等资源外层结构仍然校验;
104+
2. 已收录 schema 的 `bk-*` 插件配置会校验;
105+
3. 未收录 schema 的 `bk-*` 插件配置会跳过。
106+
107+
## 3.13 / 3.16 中的 `bk-*` schema 现状
108+
109+
两份 schema 中的 `bk-*` 插件条目完全一致,数量都是 9:
110+
111+
```text
112+
bk-access-token-source
113+
bk-cors
114+
bk-header-rewrite
115+
bk-ip-restriction
116+
bk-mock
117+
bk-rate-limit
118+
bk-request-body-limit
119+
bk-user-restriction
120+
bk-verified-user-exempted-apps
121+
```
122+
123+
其中 `bk-header-rewrite``bk-rate-limit` 不直接对应远端 `src/apisix/plugins/` 下的顶层 `bk-*.lua` 文件名:
124+
125+
- 远端有 `bk-stage-header-rewrite.lua` / `bk-resource-header-rewrite.lua`,schema 中是更泛化的 `bk-header-rewrite`
126+
- 远端目录中有 `bk-rate-limit/` 目录,同时顶层插件文件列表里没有 `bk-rate-limit.lua`
127+
128+
## 远端 `blueking-apigateway-apisix` master 插件现状
129+
130+
检查来源:
131+
132+
`https://github.com/TencentBlueKing/blueking-apigateway-apisix/tree/master/src/apisix/plugins`
133+
134+
当前远端顶层 `bk-*.lua` 插件文件共 46 个:
135+
136+
```text
137+
bk-access-token-source
138+
bk-auth-validate
139+
bk-auth-verify
140+
bk-backend-context
141+
bk-break-recursive-call
142+
bk-concurrency-limit
143+
bk-cors
144+
bk-debug
145+
bk-default-tenant
146+
bk-delete-cookie
147+
bk-delete-sensitive
148+
bk-error-wrapper
149+
bk-ip-restriction
150+
bk-jwt
151+
bk-legacy-invalid-params
152+
bk-log-context
153+
bk-mock
154+
bk-not-found-handler
155+
bk-oauth2-audience-validate
156+
bk-oauth2-protected-resource
157+
bk-oauth2-verify
158+
bk-opentelemetry
159+
bk-permission
160+
bk-proxy-rewrite
161+
bk-query-string-rewrite
162+
bk-real-ip
163+
bk-repl-debugger
164+
bk-request-body-limit
165+
bk-request-id
166+
bk-resource-context
167+
bk-resource-header-rewrite
168+
bk-resource-rate-limit
169+
bk-response-check
170+
bk-stage-context
171+
bk-stage-global-rate-limit
172+
bk-stage-header-rewrite
173+
bk-stage-rate-limit
174+
bk-status-rewrite
175+
bk-tenant-restriction
176+
bk-tenant-validate
177+
bk-tenant-validate-exempt
178+
bk-tenant-verify
179+
bk-traffic-label
180+
bk-user-restriction
181+
bk-username-required
182+
bk-verified-user-exempted-apps
183+
```
184+
185+
## 远端存在但 operator schema 缺失的顶层 `bk-*.lua` 插件
186+
187+
以下 39 个远端顶层插件名,在 `3.13/schema.json``3.16/schema.json` 中都没有对应 `plugins.<name>` 条目:
188+
189+
```text
190+
bk-auth-validate
191+
bk-auth-verify
192+
bk-backend-context
193+
bk-break-recursive-call
194+
bk-concurrency-limit
195+
bk-debug
196+
bk-default-tenant
197+
bk-delete-cookie
198+
bk-delete-sensitive
199+
bk-error-wrapper
200+
bk-jwt
201+
bk-legacy-invalid-params
202+
bk-log-context
203+
bk-not-found-handler
204+
bk-oauth2-audience-validate
205+
bk-oauth2-protected-resource
206+
bk-oauth2-verify
207+
bk-opentelemetry
208+
bk-permission
209+
bk-proxy-rewrite
210+
bk-query-string-rewrite
211+
bk-real-ip
212+
bk-repl-debugger
213+
bk-request-id
214+
bk-resource-context
215+
bk-resource-header-rewrite
216+
bk-resource-rate-limit
217+
bk-response-check
218+
bk-stage-context
219+
bk-stage-global-rate-limit
220+
bk-stage-header-rewrite
221+
bk-stage-rate-limit
222+
bk-status-rewrite
223+
bk-tenant-restriction
224+
bk-tenant-validate
225+
bk-tenant-validate-exempt
226+
bk-tenant-verify
227+
bk-traffic-label
228+
bk-username-required
229+
```
230+
231+
这些插件如果出现在 route/service/plugin_metadata 的 `plugins` 中,因为插件名以 `bk-` 开头且 schema 找不到,会被 operator 的插件配置校验逻辑跳过。
232+
233+
## 为什么 schema 只有 9 个仍然能发布更多 bk 插件
234+
235+
原因是 operator 的校验策略对蓝鲸内置插件更宽松:
236+
237+
- APISIX 官方插件要求 schema 必须存在,否则报错。
238+
- 蓝鲸内置 `bk-*` 插件允许 schema 缺失,缺失时跳过插件配置校验。
239+
240+
这个策略解释了“dashboard 已支持几乎所有 bk 插件配置和发布,但 operator schema 只有 9 个”之间的差异。
241+
242+
## 风险说明
243+
244+
当前逻辑的风险不在发布失败,而在配置质量保障:
245+
246+
- 对缺失 schema 的 `bk-*` 插件,operator 不会发现字段名错误、类型错误、必填字段缺失等问题。
247+
- 这些错误可能要等 APISIX 加载插件配置或插件运行时才暴露。
248+
- 对已有 schema 的 9 个 `bk-*` 插件,operator 仍会做配置校验。
249+
250+
## 建议
251+
252+
如果近期新增的 `bk-*` 插件已经稳定并由 dashboard 暴露给用户配置,建议逐步把这些插件的 schema 补进 `3.13` / `3.16`
253+
254+
1. 优先补用户可配置、容易配错、会影响请求链路的插件。
255+
2. 对只由 operator/dashboard 固定生成、配置结构很简单的插件,可以继续依赖代码生成侧保障。
256+
3. 如果继续保留跳过逻辑,建议至少增加一个覆盖测试,明确断言“缺失 schema 的 `bk-*` 插件会跳过,缺失 schema 的非 `bk-*` 插件会失败”,避免后续维护者误解。
257+
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
结论:这个升级可做,但不是纯 bump。当前代码已经命中 Django 5.x 的明确移除项:`USE_L10N``Meta.index_together``django.utils.timezone.utc`。依赖上,DRF 3.16.0 已经支持 Django 5.2 方向,但建议至少升到 3.16.1;其它 Django 周边库建议一起小步升级后回归验证。
2+
3+
4+
5+
**必须适配**
6+
7+
1. 删除 [default.py](/root/workspace/tx/wklken/blueking-apigateway/src/dashboard/apigateway/apigateway/conf/default.py:216)`USE_L10N = True`。Django 5.0 已移除 `USE_L10N`
8+
9+
2.[core/models.py](/root/workspace/tx/wklken/blueking-apigateway/src/dashboard/apigateway/apigateway/core/models.py:716)`index_together` 改成 `Meta.indexes = [models.Index(fields=["gateway_id", "publish_id"])]`,并生成迁移。历史迁移里已有的 `index_together` 通常不直接改,先让 Django 5.2 跑 `migrate --plan` 验证。
10+
11+
3.[utils/time.py](/root/workspace/tx/wklken/blueking-apigateway/src/dashboard/apigateway/apigateway/utils/time.py:91)`timezone.utc` 改成 `datetime.timezone.utc`
12+
13+
4. MySQL 部署要确认版本和字符集:Django 5.0 要求 MySQL >= 8.0.11;Django 5.2 默认 MySQL 连接字符集变为 `utf8mb4`。如果存量库还依赖 `utf8mb3`,需要显式配置 `DATABASES[*]["OPTIONS"]["charset"]`,但优先推动库表统一到 `utf8mb4`
14+
15+
5. 当前 `.venv` 实测是 Django 4.2.23,但 [pyproject.toml](/root/workspace/tx/wklken/blueking-apigateway/src/dashboard/pyproject.toml:8) 写的是 4.2.26。开始前先 `uv sync`,否则验证结论不可信。
16+
17+
18+
19+
**依赖建议**
20+
21+
- `django==5.2.14`:目标版本已在 2026-05-05 发布,包含 5.2.13 后的 3 个 low severity 安全修复。
22+
23+
- `djangorestframework==3.16.1`:推荐最小风险路径。DRF 3.16 官方支持 Django 5.1/5.2,并且 3.16.1 修了 `unique_together``UniqueTogetherValidator` 相关问题;本项目大量使用 `unique_together``SerializerMethodField` 和 DRF validators。
24+
25+
- `drf-yasg==1.21.15`:建议同步升级。当前 `manage.py check` 已有 renderer format 兼容警告,升级后重点测 `/backend/docs/auto/swagger.json``swagger.yaml`、Swagger UI、Redoc。
26+
27+
- `django-celery-beat==2.9.0`:建议同步升级,跑它的 migrations plan,并验证现有 periodic tasks。
28+
29+
- `django-cors-headers==4.9.0``django-filter==25.2``djangoql==0.19.1`:建议同步升级;`djangoql` 在 admin 里用得很广,要做 admin 搜索冒烟测试。
30+
31+
- `jsonfield==3.1.0`:不是 Django 5.2 明确 blocker,但它很老;本项目仍有 legacy `jsonfield.JSONField` 和本地 wrapper [utils/django.py](/root/workspace/tx/wklken/blueking-apigateway/src/dashboard/apigateway/apigateway/utils/django.py:35)。不要和 Django 升级混在一起大迁移到 `models.JSONField`,先保留并用测试兜住。
32+
33+
- `django-nose`/`nose`:测试配置里已禁用 nose 插件,属于后续清理项,不建议塞进这次升级。
34+
35+
36+
37+
**升级步骤**
38+
39+
1. 基线同步:`uv sync`,确认 `python3 -c "import django; print(django.get_version())"` 是 4.2.26。
40+
41+
2. 在 4.2.26 下先跑:`PYTHONWARNINGS=always python3 -Wa manage.py check`,把现有 deprecation warnings 清掉。当前已确认会报 `USE_L10N``index_together``drf-yasg` renderer warning。
42+
43+
3. 先做三处代码适配:删除 `USE_L10N`、替换 `timezone.utc`、迁移 `index_together``indexes`
44+
45+
4. 更新 `pyproject.toml`:Django 5.2.14 + 上面的 Django 周边库版本,然后 `make uv.lock && uv sync`
46+
47+
5. 跑静态/框架检查:`python3 -Wa manage.py check``python3 manage.py makemigrations --check --dry-run``python3 manage.py migrate --plan`
48+
49+
6. 跑重点回归:DRF 权限/认证、OpenAPI schema 生成、admin + djangoql 搜索、celery beat migrations、JSONField 读写、批量写入 `bulk_create`、MySQL 环境迁移。
50+
51+
7. 最后跑项目要求的 `make lint``make test`。如果只改依赖和适配代码,不要跳过。
52+
53+
54+
55+
官方依据:Django 升级指南要求读每个 final release notes 和 deprecation timeline;5.0 移除了 `USE_L10N`/`timezone.utc`,5.1 移除了 `Meta.index_together`,5.2 改了 MySQL 默认字符集并是 LTS;DRF 3.16 官方说明支持 Django 5.2,3.16.1 修了本项目相关的 unique validator 问题。
56+
57+
Sources: Django upgrade guide, release notes index, 5.0/5.1/5.2/5.2.14 release notes, DRF 3.16 announcement and release notes.
58+
59+
60+
I’d change the recommendation to **DRF 3.17.1**, not 3.17.0.
61+
62+
63+
64+
Reason: DRF 3.16 already supports Django 5.2, so 3.17 is not required for Django 5.2. But 3.17.1 is reasonable in this upgrade branch because we are already doing a framework compatibility pass, and it includes relevant fixes around `UniqueTogetherValidator`, M2M validation, `HTMLFormRenderer`, `OrderingFilter`, and token admin behavior.
65+
66+
67+
68+
The main breaking change is that **DRF 3.17.0 drops deprecated CoreAPI support**. I checked the repo and didn’t find direct `coreapi`, `coreschema`, `rest_framework.schemas.coreapi`, `DEFAULT_SCHEMA_CLASS`, or `include_docs_urls` usage under `apigateway/apigateway`, so this looks low risk. Still, because this project uses `drf-yasg` heavily, the required smoke tests are:
69+
70+
71+
72+
```bash
73+
74+
/backend/docs/auto/swagger.json
75+
76+
/backend/docs/auto/swagger.yaml
77+
78+
/backend/docs/auto/swagger/
79+
80+
/backend/docs/auto/redoc/
81+
82+
```
83+
84+
85+
86+
So the updated dependency plan should be:
87+
88+
89+
90+
```toml
91+
92+
django==5.2.14
93+
94+
djangorestframework==3.17.1
95+
96+
drf-yasg==1.21.15
97+
98+
django-filter==25.2
99+
100+
django-celery-beat==2.9.0
101+
102+
django-cors-headers==4.9.0
103+
104+
djangoql==0.19.1
105+
106+
```
107+
108+
109+
110+
Sources: DRF release notes list 3.17.1 as latest, 3.17.0 breaking changes, and 3.17.x bug fixes: https://www.django-rest-framework.org/community/release-notes/

0 commit comments

Comments
 (0)