控制平面 API 参考(v1)
基础地址:http://localhost:8000
- 内容类型:
application/json - 错误格式:
{ "detail": string } - 认证方式:
- 会话 Cookie(通过
POST /api/v1/auth/login获取) - Bearer Token(
Authorization: Bearer <token>;可使用环境变量MASTER_API_TOKEN指定的主令牌,或通过/api/v1/auth/tokens管理的服务令牌)
- 会话 Cookie(通过
约定
- 除特别说明外,端点均需通过会话 Cookie 或 Bearer Token 认证。
- 管理令牌的端点(
/api/v1/auth/tokens)需要主令牌。 - 错误响应统一为
{ "detail": string },并配合相应的 HTTP 状态码。 - 路径参数以
{param}表示(例如{domain})。
数据模型
Upstream(回源)
| 字段 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| scheme | string | 是 | 源站协议 | "http" / "https" |
| host | string | 是 | 源站主机名 | "origin.example.com" |
| port | integer | 是 | 源站端口 | 80 |
| weight | integer | 是 | 加权轮询权重 | 1 |
Rule(缓存规则)
| 字段 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| path | string | 是 | 路径前缀或正则(由 OpenResty 解释) | "^/assets/" |
| ttl | integer | 是 | 缓存 TTL(秒) | 600 |
| methods | string[] | 是 | 允许的方法 | ["GET","HEAD"] |
| slice | boolean | 否 | 按规则启用切片(覆盖全局设置) | false |
DomainConf(域名配置)
| 字段 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| origins | Upstream[] | 是 | 上游源站列表 | [Upstream, ...] |
| upstream_headers | object | 否 | 回源时附加请求头 | {"X-From":"CDN"} |
| cache_enable | boolean | 是 | 是否启用缓存 | true |
| slice_enable | boolean | 是 | 是否启用切片 | false |
| rules | Rule[] | 是 | 缓存规则列表 | [Rule, ...] |
| use_acme_dns01 | boolean | 否 | 是否启用 ACME dns-01 | false |
| acme_cname_target | string/null | 否 | _acme-challenge 的目标 CNAME(acme-dns 注册后回填) | null |
CacheUpdate(PUT /cache-rules)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cache_enable | boolean | 否 | 切换是否启用缓存 |
| slice_enable | boolean | 否 | 切换是否启用切片 |
| rules | Rule[] | 否 | 缓存规则 |
UpstreamsPayload(PUT /upstreams)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| origins | Upstream[] | 是 | 上游源站列表(全量覆盖) |
CertPayload(PUT /cert)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| fullchain_pem | string | 是 | 证书链 PEM |
| key_pem | string | 是 | 私钥 PEM |
AssignedNode
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 节点标识 |
| a | string | IPv4(或 null) |
| aaaa | string | IPv6(或 null) |
端点
GET /healthz
- 成功 200:
{ "ok": true } - 失败 500:
{ "detail": string }
示例请求
curl -s http://localhost:8000/healthz
示例响应
{ "ok": true }
POST /api/v1/auth/login
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名 |
| password | string | 是 | 密码 |
- 成功 200:
{ "ok": true }(设置会话 Cookie) - 失败:
401 invalid credentials、403 password authentication disabled
示例请求
curl -i -X POST 'http://localhost:8000/api/v1/auth/login' \
-H 'Content-Type: application/json' \
-d '{"username":"admin","password":"******"}'
示例响应
{ "ok": true }
POST /api/v1/auth/logout
- 成功 200:
{ "ok": true }(清除会话 Cookie)
GET /api/v1/auth/me
成功 200
| 字段 | 类型 | 说明 |
|---|---|---|
| username | string | 当前用户名 |
| auth_method | string | session / token / master / dev |
| token_id | string/null | 服务令牌 id(主令牌为 null) |
示例请求
curl -s 'http://localhost:8000/api/v1/auth/me' -b cookies.txt -c cookies.txt
示例响应
{ "username": "admin", "auth_method": "session", "token_id": null }
GET /api/v1/auth/tokens
- 需主令牌
- 成功 200
| 字段 | 类型 | 说明 |
|---|---|---|
| tokens | array | 令牌对象数组 |
令牌对象(Token)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 令牌 id |
| label | string | 标签 |
| created_at | string(ISO 8601) | 创建时间 |
| last_used_at | string/null | 上次使用时间 |
| suffix | string | 令牌明文后两位 |
示例请求
curl -s 'http://localhost:8000/api/v1/auth/tokens' \
-H 'Authorization: Bearer ${MASTER_API_TOKEN}'
POST /api/v1/auth/tokens
- 需主令牌 请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| label | string | 是 | 令牌标签 |
- 成功 200:返回 Token 对象并附加一次性字段
| 额外字段 | 类型 | 说明 |
|---|---|---|
| token | string | 完整令牌(仅返回一次) |
示例请求
curl -s -X POST 'http://localhost:8000/api/v1/auth/tokens' \
-H 'Authorization: Bearer ${MASTER_API_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{"label":"ci token"}'
示例响应
{
"id": "4f8a1c9e5d3b",
"label": "ci token",
"created_at": "2024-04-02T07:20:00+00:00",
"last_used_at": null,
"suffix": "3b",
"token": "qjP...<one-time>..."
}
DELETE /api/v1/auth/tokens/{token_id}
- 需主令牌
- 成功 200:
{ "ok": true }
GET /api/v1/users
成功 200
| 字段 | 类型 | 说明 |
|---|---|---|
| users | array | 用户对象数组 |
用户对象(User)
| 字段 | 类型 | 说明 |
|---|---|---|
| username | string | 用户名 |
| string | 邮箱(可为空) | |
| status | string | "Active" / "Inactive" |
| lastLogin | string | "Never" 或时间戳 |
示例请求
curl -s 'http://localhost:8000/api/v1/users' \
-H 'Authorization: Bearer <token>'
POST /api/v1/users
请求体
| 字段 | 类型 | 必填 |
|---|---|---|
| username | string | 是 |
| string | 是 | |
| password | string | 是 |
| status | string | 是("Active"/"Inactive") |
- 成功 200:
{ "ok": true } - 冲突 409:
user already exists
PUT /api/v1/users/{username}
请求体(均为可选)
| 字段 | 类型 |
|---|---|
| string | |
| password | string |
| status | string |
- 成功 200:
{ "ok": true } - 未找到 404:
user not found
DELETE /api/v1/users/{username}
- 成功 200:
{ "ok": true }
POST /api/v1/domains/{domain}
请求体:DomainConf
- 成功 200:
{ "ok": true } - 失败:
400 origins must be a non-empty list、409 domain already exists
示例请求
curl -X POST 'http://localhost:8000/api/v1/domains/example.com' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <token>' \
-d '{
"origins":[{"scheme":"http","host":"10.0.0.10","port":80,"weight":2}],
"cache_enable": true,
"slice_enable": false,
"rules": []
}'
GET /api/v1/domains
成功 200
| 字段 | 类型 | 说明 |
|---|---|---|
| domains | string[] | 域名列表 |
GET /api/v1/domains/{domain}
- 成功 200:
DomainConf - 未找到 404:
domain not found
GET /api/v1/domains/{domain}/cname
成功 200
| 字段 | 类型 | 说明 |
|---|---|---|
| access_domain | string | 接入 FQDN |
| replicas | integer | 副本数量 |
| assigned_nodes | AssignedNode[] | 分配的节点 |
| ttl | integer | TTL |
错误码
- 405:
cname is disabled
示例响应
{
"access_domain": "example.com.cdn.local.test.",
"replicas": 2,
"assigned_nodes": [
{"id":"node-1","a":"100.64.2.61","aaaa":null},
{"id":"node-2","a":"100.64.2.62","aaaa":null}
],
"ttl": 60
}
PUT /api/v1/domains/{domain}
请求体:DomainConf
- 成功 200:
{ "ok": true } - 失败:
404 domain not found、400 origins must be a non-empty list
DELETE /api/v1/domains/{domain}
- 成功 200:
{ "ok": true }(同时清理相关键)
PUT /api/v1/domains/{domain}/cache-rules
请求体:CacheUpdate
- 成功 200:
{ "ok": true }
PUT /api/v1/domains/{domain}/upstreams
请求体:UpstreamsPayload
- 成功 200:
{ "ok": true }
PUT /api/v1/domains/{domain}/cert
请求体:CertPayload
- 成功 200:
{ "ok": true } - 错误 400:
invalid PEM
GET /api/v1/domains/{domain}/acme
成功 200
响应字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| use_acme_dns01 | boolean | 是否启用 ACME |
| acme_cname_target | string/null | _acme-challenge 目标 CNAME |
| status | string | "registered" / "disabled" 等 |
| registered | boolean | 是否已在 acme-dns 注册 |
| fulldomain | string/null | acme-dns 返回的完整域名 |
| subdomain | string/null | acme-dns 使用的子域 |
POST /api/v1/domains/{domain}/acme
- 可选请求体:
{ "force_renew": true }(当前实现忽略) - 成功 202:
{ "ok": true, "task_id": string } - 冲突 409:
acme issuance already running or queued for this domain
DELETE /api/v1/domains/{domain}/acme
- 成功 200:
{ "ok": true }
POST /api/v1/purge
查询参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| domain | string | 是 | 目标域名 |
| path | string | 是 | 路径;支持前缀通配符 *(如 /images/cat*);/* 为全量清理 |
- 成功 200:
{ "ok": true }(表示消息已发布;实际清理异步完成)
示例请求
curl -X POST 'http://localhost:8000/api/v1/purge?domain=example.com&path=/images/cat*' \
-H 'Authorization: Bearer <token>'
PUT /api/v1/nodes
请求体
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nodes | array | 是 | 节点对象数组 |
节点对象(Node)
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 节点 id |
| name | string | 显示名称 |
| a | string | IPv4 |
| aaaa | string/null | IPv6 |
- 说明:不接收
active字段(由健康检查维护);更新会触发 CNAME 区域重建与分发。 - 成功 200:
{ "ok": true, "count": number }
示例请求
curl -X PUT 'http://localhost:8000/api/v1/nodes' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"nodes": [
{"id":"node-1","name":"edge-1","a":"100.64.2.61","aaaa":null},
{"id":"node-2","name":"edge-2","a":"100.64.2.62","aaaa":null}
]
}'