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'} 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'}