proxy-pool/api/openapi/admin.yaml

296 lines
11 KiB
YAML

openapi: 3.1.0
info:
title: Proxy Pool Admin API
version: 1.0.0
description: 运维状态与受控变更接口。该入口必须与 Distribution 分端口和权限。
servers:
- url: http://127.0.0.1:8082
tags:
- name: Status
- name: Upstreams
- name: Routing
- name: Configuration
security:
- AdminApiKey: []
- BasicAuth: []
- BearerAuth: []
- {}
paths:
/api/v1/status:
get:
tags: [Status]
operationId: getStatus
summary: 获取控制面摘要状态
responses:
'200':
description: 不含 Proxy 地址、Client 标识或 Secret 的聚合状态
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/json:
schema:
$ref: '#/components/schemas/Status'
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'400': {$ref: '#/components/responses/BadRequest'}
'405': {$ref: '#/components/responses/MethodNotAllowed'}
'500': {$ref: '#/components/responses/InternalServerError'}
'503': {$ref: '#/components/responses/ServiceUnavailable'}
/api/v1/upstreams/{name}/enable:
post:
tags: [Upstreams]
operationId: enableUpstream
summary: 启用 Upstream
parameters:
- $ref: '#/components/parameters/UpstreamName'
- $ref: '#/components/parameters/RequestID'
responses:
'200': {$ref: '#/components/responses/MutationResult'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'404': {$ref: '#/components/responses/NotFound'}
'409': {$ref: '#/components/responses/Conflict'}
'400': {$ref: '#/components/responses/BadRequest'}
'405': {$ref: '#/components/responses/MethodNotAllowed'}
'500': {$ref: '#/components/responses/InternalServerError'}
'503': {$ref: '#/components/responses/ServiceUnavailable'}
/api/v1/upstreams/{name}/disable:
post:
tags: [Upstreams]
operationId: disableUpstream
summary: 禁用 Upstream 并使已有资源自然 Drain
parameters:
- $ref: '#/components/parameters/UpstreamName'
- $ref: '#/components/parameters/RequestID'
responses:
'200': {$ref: '#/components/responses/MutationResult'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'404': {$ref: '#/components/responses/NotFound'}
'409': {$ref: '#/components/responses/Conflict'}
'400': {$ref: '#/components/responses/BadRequest'}
'405': {$ref: '#/components/responses/MethodNotAllowed'}
'500': {$ref: '#/components/responses/InternalServerError'}
'503': {$ref: '#/components/responses/ServiceUnavailable'}
/api/v1/routing/{name}/switch:
post:
tags: [Routing]
operationId: switchRouting
summary: 原子切换 Sequential Routing 当前 Upstream
parameters:
- name: name
in: path
required: true
schema: {type: string, minLength: 1, maxLength: 128}
- $ref: '#/components/parameters/RequestID'
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: false
required: [expectedCurrent, target]
properties:
expectedCurrent: {type: string}
target: {type: string}
reason: {type: string, maxLength: 512}
responses:
'200': {$ref: '#/components/responses/MutationResult'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'404': {$ref: '#/components/responses/NotFound'}
'409': {$ref: '#/components/responses/Conflict'}
'400': {$ref: '#/components/responses/BadRequest'}
'405': {$ref: '#/components/responses/MethodNotAllowed'}
'413': {$ref: '#/components/responses/RequestEntityTooLarge'}
'415': {$ref: '#/components/responses/UnsupportedMediaType'}
'422': {$ref: '#/components/responses/UnprocessableEntity'}
'500': {$ref: '#/components/responses/InternalServerError'}
'503': {$ref: '#/components/responses/ServiceUnavailable'}
/api/v1/config/reload:
post:
tags: [Configuration]
operationId: reloadConfiguration
summary: 严格校验并原子发布新配置快照
parameters:
- $ref: '#/components/parameters/RequestID'
responses:
'200': {$ref: '#/components/responses/MutationResult'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'409': {$ref: '#/components/responses/Conflict'}
'400': {$ref: '#/components/responses/BadRequest'}
'405': {$ref: '#/components/responses/MethodNotAllowed'}
'422':
description: 新配置无效,旧配置继续运行
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
'500': {$ref: '#/components/responses/InternalServerError'}
'503': {$ref: '#/components/responses/ServiceUnavailable'}
components:
securitySchemes:
AdminApiKey: {type: apiKey, in: header, name: X-Admin-Key}
BasicAuth: {type: http, scheme: basic}
BearerAuth: {type: http, scheme: bearer}
parameters:
UpstreamName:
name: name
in: path
required: true
schema: {type: string, minLength: 1, maxLength: 128}
RequestID:
name: X-Request-ID
in: header
required: false
schema: {type: string, maxLength: 128}
headers:
RequestID:
description: 服务端最终使用的请求标识。
schema: {type: string, maxLength: 128}
schemas:
Status:
type: object
additionalProperties: false
required: [configVersion, snapshotVersion, upstreams, workers]
properties:
configVersion: {type: string}
snapshotVersion: {type: integer, minimum: 0}
upstreams:
type: array
items:
type: object
additionalProperties: false
required: [name, enabled, available, checking, suspect, draining, extracted]
properties:
name: {type: string}
enabled: {type: boolean}
available: {type: integer, minimum: 0}
checking: {type: integer, minimum: 0}
suspect: {type: integer, minimum: 0}
draining: {type: integer, minimum: 0}
extracted: {type: integer, minimum: 0}
consecutiveEmptyFetch: {type: integer, minimum: 0}
fetchErrorCount: {type: integer, minimum: 0}
workers:
type: array
items:
type: object
additionalProperties: false
required: [id, zone, connected, snapshotVersion]
properties:
id: {type: string}
zone: {type: string}
connected: {type: boolean}
snapshotVersion: {type: integer, minimum: 0}
staleSeconds: {type: integer, minimum: 0}
MutationResult:
type: object
additionalProperties: false
required: [requestId, changed, version]
properties:
requestId: {type: string}
changed: {type: boolean}
version: {type: integer, minimum: 0}
message: {type: string}
Problem:
type: object
required: [type, title, status, code]
properties:
type: {type: string, format: uri}
title: {type: string}
status: {type: integer}
code: {type: string}
detail: {type: string}
requestId: {type: string}
responses:
MutationResult:
description: 操作已提交或目标状态原本已满足
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/json:
schema: {$ref: '#/components/schemas/MutationResult'}
Unauthorized:
description: 管理入口认证失败
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
WWW-Authenticate: {schema: {type: string}}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
Forbidden:
description: 调用主体无该管理权限
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
NotFound:
description: Upstream 或 Routing 不存在
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
Conflict:
description: 预期版本或 expectedCurrent 与权威状态不一致
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
BadRequest:
description: 请求标识或请求体无效
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
MethodNotAllowed:
description: 端点不支持该 HTTP 方法
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
Allow: {schema: {type: string}}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
RequestEntityTooLarge:
description: 请求体超过管理入口限制
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
UnsupportedMediaType:
description: Content-Type 不是 application/json
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
UnprocessableEntity:
description: 命令字段或配置内容违反业务约束
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
InternalServerError:
description: 未分类的控制面错误
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}
ServiceUnavailable:
description: 权威控制面暂时不可用
headers:
X-Request-ID: {$ref: '#/components/headers/RequestID'}
content:
application/problem+json:
schema: {$ref: '#/components/schemas/Problem'}