## 分层回源 L2 (`l2`)

边缘回源先经同区域的 L2 节点,L2 有缓存就不再打源站;付费功能 l2,未开通时整块不生效。

鉴权: 仅管理员 · 文档: https://www-demo.kuxitong.com/zh/docs/api/l2

### POST `/api/v2/l2/enable-batch`

批量加 L2 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `apply_sites` | boolean |  | 给现有网站也开(只动从没设过的网站,手动关过的、所属租户套餐不含分层回源的不动)。 |
| `node_ids` | integer[] | 有 | 要改做 L2 的边缘节点 id。 |

```sh
curl -X POST "https://panel.example.com/api/v2/l2/enable-batch" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/groups`

列出 L2 组 · 鉴权: 仅管理员

```sh
curl "https://panel.example.com/api/v2/l2/groups" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/l2/groups`

新建 L2 组 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `all_regions` | boolean |  | 服务全部区域(须勾跨区域)。 |
| `balance` | string |  | 分配方式:url_hash 按网址固定,rr 轮流。 可选值: ["url_hash","rr"] |
| `cross_region` | boolean |  | 允许跨区域使用(选了区域外的节点或全部区域必须勾,多约 50–200 毫秒)。 |
| `name` | string | 有 | 组名,全平台唯一。 |
| `node_ids` | integer[] |  | 要改做 L2 的边缘节点 id。 |
| `regions` | integer[] |  | 服务区域 id;all_regions 为真时忽略。 |
| `rules` | L2Rule[] |  | 组内规则(随组保存)。 |

```sh
curl -X POST "https://panel.example.com/api/v2/l2/groups" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/groups/{id}`

查看 L2 组 · 鉴权: 仅管理员

```sh
curl "https://panel.example.com/api/v2/l2/groups/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### PATCH `/api/v2/l2/groups/{id}`

修改 L2 组 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `all_regions` | boolean |  | 服务全部区域(须勾跨区域)。 |
| `balance` | string |  | 分配方式:url_hash 按网址固定,rr 轮流。 可选值: ["url_hash","rr"] |
| `cross_region` | boolean |  | 允许跨区域使用(选了区域外的节点或全部区域必须勾,多约 50–200 毫秒)。 |
| `name` | string |  | 组名,全平台唯一。 |
| `node_ids` | integer[] |  | 要改做 L2 的边缘节点 id。 |
| `regions` | integer[] |  | 服务区域 id;all_regions 为真时忽略。 |
| `rules` | L2Rule[] |  | 组内规则(随组保存)。 |

```sh
curl -X PATCH "https://panel.example.com/api/v2/l2/groups/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### DELETE `/api/v2/l2/groups/{id}`

删除 L2 组 · 鉴权: 仅管理员

```sh
curl -X DELETE "https://panel.example.com/api/v2/l2/groups/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/l2/groups/{id}/copy`

复制 L2 组 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `name` | string | 有 | 组名,全平台唯一。 |

```sh
curl -X POST "https://panel.example.com/api/v2/l2/groups/{id}/copy" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/l2/groups/{id}/reset-sites`

把用这个组的网站改回区域默认 · 鉴权: 仅管理员

```sh
curl -X POST "https://panel.example.com/api/v2/l2/groups/{id}/reset-sites" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/nodes`

列出 L2 节点 · 鉴权: 仅管理员

```sh
curl "https://panel.example.com/api/v2/l2/nodes" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### PATCH `/api/v2/l2/nodes/{id}`

修改 L2 节点 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `access_addr` | string |  | 边缘访问它的内网地址(只收 IP,不带端口;IPv4 映射的 IPv6 存成 IPv4);空 = 公网 IP。 |
| `role` | string |  | 主备:同组有主可用时备只待命,主全挂才用备(在组内成员间比较)。 可选值: ["primary","backup"] |
| `weight` | integer |  | 权重 1–100,多台主按权重分网址。 |

```sh
curl -X PATCH "https://panel.example.com/api/v2/l2/nodes/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/l2/nodes/{id}/disable`

停用 L2 节点 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `reason` | string |  | 停用原因。 |

```sh
curl -X POST "https://panel.example.com/api/v2/l2/nodes/{id}/disable" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/l2/nodes/{id}/enable`

启用 L2 节点 · 鉴权: 仅管理员

```sh
curl -X POST "https://panel.example.com/api/v2/l2/nodes/{id}/enable" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/nodes/{id}/impact`

改回 / 停用前的影响 · 鉴权: 仅管理员

```sh
curl "https://panel.example.com/api/v2/l2/nodes/{id}/impact" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/l2/nodes/{id}/mark-allowed`

标记源站已放行 · 鉴权: 仅管理员

```sh
curl -X POST "https://panel.example.com/api/v2/l2/nodes/{id}/mark-allowed" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/l2/nodes/{id}/probe-access`

检测源站是否已放行 · 鉴权: 仅管理员

```sh
curl -X POST "https://panel.example.com/api/v2/l2/nodes/{id}/probe-access" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/l2/nodes/{id}/revert`

改回边缘节点 · 鉴权: 仅管理员

```sh
curl -X POST "https://panel.example.com/api/v2/l2/nodes/{id}/revert" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/l2/pause`

全网暂停分层回源 · 鉴权: 仅管理员

请求体:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `auto_resume_at` | string |  | 自动恢复时刻(须在现在之后);不给 = 手动恢复。 |

```sh
curl -X POST "https://panel.example.com/api/v2/l2/pause" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/recommend`

一键启用推荐 · 鉴权: 仅管理员

```sh
curl "https://panel.example.com/api/v2/l2/recommend" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### POST `/api/v2/l2/resume`

全网恢复分层回源 · 鉴权: 仅管理员

```sh
curl -X POST "https://panel.example.com/api/v2/l2/resume" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/revoke-impact`

授权失效的影响与回落窗口 · 鉴权: 仅管理员

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `page` | integer |  | 页码,从 1 开始。 默认: 1 |
| `page_size` | integer |  | 每页条数。 默认: 20 |

```sh
curl "https://panel.example.com/api/v2/l2/revoke-impact" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/stats`

分层回源统计 · 鉴权: 仅管理员

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `start` | string | 有 | 起始时间(含),RFC 3339。 |
| `end` | string | 有 | 结束时间(不含),RFC 3339。 |

```sh
curl "https://panel.example.com/api/v2/l2/stats" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/stats/nodes`

按 L2 节点的统计 · 鉴权: 仅管理员

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `start` | string | 有 | 起始时间(含),RFC 3339。 |
| `end` | string | 有 | 结束时间(不含),RFC 3339。 |

```sh
curl "https://panel.example.com/api/v2/l2/stats/nodes" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/stats/sites`

按网站的分层回源统计 · 鉴权: 仅管理员

查询参数:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `start` | string | 有 | 起始时间(含),RFC 3339。 |
| `end` | string | 有 | 结束时间(不含),RFC 3339。 |
| `page` | integer |  | 页码,从 1 开始。 默认: 1 |
| `page_size` | integer |  | 每页条数。 默认: 20 |
| `domain` | string |  | 主域名子串,不分大小写。 |

```sh
curl "https://panel.example.com/api/v2/l2/stats/sites" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/status`

分层回源总览 · 鉴权: 仅管理员

```sh
curl "https://panel.example.com/api/v2/l2/status" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

### GET `/api/v2/l2/tasks/{id}`

查看 L2 任务进度 · 鉴权: 仅管理员

```sh
curl "https://panel.example.com/api/v2/l2/tasks/{id}" \
  -H "X-API-Key: $GOCDN_API_KEY"
```

分层回源 L2对象:

| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| `access_addr` | string |  | 边缘访问它的内网地址(只收 IP,不带端口;IPv4 映射的 IPv6 存成 IPv4);空 = 公网 IP。 |
| `all_regions` | boolean |  | 服务全部区域(须勾跨区域)。 |
| `allow` | string |  | 源站放行:空 = 不涉及(没有网站只允许 L2),pending 待放行(只接可缓存请求),allowed 已放行。 |
| `allow_since` | string |  | 进入待放行的时刻;满 24 小时自动转已放行。 |
| `apply_sites` | boolean |  | 给现有网站也开(只动从没设过的网站,手动关过的、所属租户套餐不含分层回源的不动)。 |
| `auto_resume_at` | string |  | 自动恢复时刻(须在现在之后);不给 = 手动恢复。 |
| `balance` | string |  | 分配方式:url_hash 按网址固定,rr 轮流。 可选值: ["url_hash","rr"] |
| `checked_at` | string |  | 检测时刻。 |
| `created_at` | string |  | 开始时间。 |
| `cross_region` | boolean |  | 允许跨区域使用(选了区域外的节点或全部区域必须勾,多约 50–200 毫秒)。 |
| `defaults` | L2Defaults |  | 默认设置(改用 PUT /configs/l2.defaults)。 |
| `disabled_at` | string |  | 停用时刻。 |
| `disabled_reason` | string |  | 停用原因。 |
| `edge_origin_requests` | integer |  | 边缘回源请求数(命中率分母)。 |
| `empty_group` | integer[] |  | 去掉它后没有可用 L2 的组(用这些组的网站将暂时绕过)。 |
| `enabled` | boolean |  | 启用;停用时仍是 L2、缓存保留。 |
| `feature` | string |  | 付费功能 l2 开通档:on 开通;limited 冻结、即将停用或授权失效后的回落窗口(照常下发,只能停用、暂停等,见 GET /l2/revoke-impact);off 没开通(不下发)。 可选值: ["on","limited","off"] |
| `finished_at` | string |  | 结束时间。 |
| `groups` | integer[] |  | 所在 L2 组 id。 |
| `hit_rate` | number |  | 命中率 0–1;没有回源为 0。 |
| `host` | string |  | 网站主域名。 |
| `id` | integer |  | 组 id。 |
| `ip` | string |  | 公网 IP。 |
| `is_region_default` | boolean |  | 区域默认组(每区域一个,不能删,只能改分配方式)。 |
| `items` | L2Group[] |  | L2 组。 |
| `kind` | string |  | 任务种类:enable 加 L2,revert 改回边缘。 可选值: ["enable","revert"] |
| `l2_group_id` | integer |  | 网站选的 L2 组;null = 区域默认。 |
| `l2_group_name` | string |  | L2 组名;区域默认时为空串。 |
| `l2_hit_requests` | integer |  | L2 接住的回源请求数(命中率分子)。 |
| `l2_pick` | string |  | 网站生效的选 L2 方式(网站单独设的,否则默认设置):region 跟边缘同区域;near 离源站最近。 可选值: ["region","near"] |
| `low_hit` | boolean |  | 命中率低于 30% 且源站请求不少于 1000 次(动态内容多,建议关)。 |
| `manual_off_sites` | integer |  | 手动关过分层回源的网站数(一键启用勾「给现有网站也开」时不动它们;IP 站不计)。 |
| `name` | string | 有 | 组名,全平台唯一。 |
| `node_id` | integer |  | 节点 id。 |
| `node_ids` | integer[] | 有 | 要改做 L2 的边缘节点 id。 |
| `nodes_pending` | integer |  | 待放行的 L2 数。 |
| `nodes_serving` | integer |  | 在接回源的 L2 数(启用且没在改回)。 |
| `nodes_total` | integer |  | L2 节点总数(含停用、改回中)。 |
| `online` | boolean |  | 在线(最近 2 分钟有心跳)。 |
| `only_block` | boolean |  | 有网站开了「源站只允许 L2 访问」(改回后源站要撤掉它的放行)。 |
| `only_block_sites` | integer |  | 开了「源站只允许 L2 访问」的网站数(only_block 为真时大于 0)。 |
| `origin_l2_only` | boolean |  | 开了「源站只允许 L2 访问」:回落窗口满后源站没放行边缘节点就会整站不可用。 |
| `origin_requests` | integer |  | 实际到源站的请求数。 |
| `origin_requests_est` | integer |  | 未开分层时的估算(= 边缘回源请求数)。 |
| `owner_id` | integer |  | 所属用户 ID。 |
| `owner_name` | string |  | 所属用户名。 |
| `paused` | boolean |  | 全网暂停中。 |
| `paused_at` | string |  | 暂停时刻。 |
| `progress` | integer |  | 进度 0–100。 |
| `reason` | string |  | 停用原因。 |
| `region_id` | integer |  | 区域默认组所属区域;自建组 0。 |
| `region_last` | boolean |  | 它是本区域最后一台启用中的 L2。 |
| `regions` | integer[] |  | 服务区域 id;all_regions 为真时忽略。 |
| `revert_at` | string |  | 开始改回的时刻。 |
| `role` | string |  | 主备:同组有主可用时备只待命,主全挂才用备(在组内成员间比较)。 可选值: ["primary","backup"] |
| `rules` | L2Rule[] |  | 组内规则(随组保存)。 |
| `saved_bytes` | integer |  | 省的回源流量(L2 命中字节)。 |
| `site_id` | integer |  | 网站 ID。 |
| `sites` | integer |  | 用这个组的网站数;区域默认组为开着 L2 且没指定组的网站数(各区域默认组同数)。 |
| `sites_only_l2` | integer |  | 开了「源站只允许 L2 访问」的网站数(暂停、新加节点时写进提醒)。 |
| `state` | string |  | 状态:active 正常,reverting 改回边缘中。 可选值: ["active","reverting"] |
| `thresholds` | L2Thresholds |  | 判定阈值(只读)。 |
| `updated_at` | string |  | 最后修改时间。 |
| `weight` | integer |  | 权重 1–100,多台主按权重分网址。 |
