docs(delivery): add Swagger annotations and regenerate API docs

Add Swagger annotations to all 7 delivery handlers. Fix existing
test.go type references (Response -> response.Response). Add swaggo
dependencies to go.mod. Regenerate swagger.json/yaml/docs.go with
delivery endpoints visible in /swagger/index.html.

Relates-to: #97
This commit is contained in:
mac
2026-07-23 13:50:21 +08:00
parent 5ddb434b74
commit c421be3ae9
6 changed files with 1429 additions and 66 deletions
+525 -19
View File
@@ -24,6 +24,357 @@ const docTemplate = `{
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/auth/api/v1/delivery/mysql": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "创建一个 MySQL 交付任务,调度器会自动分配主机、调用 AWX 执行部署",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "提交 MySQL 一键交付",
"parameters": [
{
"type": "string",
"description": "幂等键(防重复提交,最长 128 字符)",
"name": "Idempotency-Key",
"in": "header",
"required": true
},
{
"description": "交付参数",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/service.MySQLDeliveryInput"
}
}
],
"responses": {
"200": {
"description": "幂等重放(相同 Idempotency-Key 已存在)",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"202": {
"description": "任务已创建",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "参数错误",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/auth/api/v1/delivery/quotas": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "管理员为指定业务线 + 部署目标设置资源配额",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "创建或更新资源配额",
"parameters": [
{
"description": "配额参数",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handler.quotaPayload"
}
}
],
"responses": {
"200": {
"description": "配额已更新",
"schema": {
"$ref": "#/definitions/model.ResourceQuota"
}
},
"400": {
"description": "参数错误",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/auth/api/v1/delivery/targets": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "返回所有已启用的部署目标(如 k8s 集群、主机池)",
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "获取可用部署目标",
"responses": {
"200": {
"description": "items: 部署目标数组",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "内部错误",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "管理员创建新的部署目标(目前仅支持 k8s 类型)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "创建部署目标",
"parameters": [
{
"description": "目标配置",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handler.targetPayload"
}
}
],
"responses": {
"201": {
"description": "目标已创建",
"schema": {
"$ref": "#/definitions/model.DeploymentTarget"
}
},
"400": {
"description": "参数错误",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"409": {
"description": "名称冲突",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/auth/api/v1/delivery/tasks": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "返回当前用户可见的交付任务列表(管理员可见全部)",
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "获取交付任务列表",
"parameters": [
{
"type": "integer",
"description": "业务线 ID 过滤",
"name": "business_line_id",
"in": "query"
}
],
"responses": {
"200": {
"description": "items: 任务数组",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/auth/api/v1/delivery/tasks/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "返回指定任务的详细信息及事件流",
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "获取交付任务详情",
"parameters": [
{
"type": "string",
"description": "任务 ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "task + events",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"404": {
"description": "任务不存在",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/auth/api/v1/delivery/tasks/{id}/cancel": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "取消一个正在执行或等待中的交付任务",
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "取消交付任务",
"parameters": [
{
"type": "string",
"description": "任务 ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "ok: true",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"409": {
"description": "无法取消(状态冲突)",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/ping": {
"get": {
"description": "检查服务器是否正常运行",
@@ -43,7 +394,7 @@ const docTemplate = `{
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
},
{
"type": "object",
@@ -81,7 +432,7 @@ const docTemplate = `{
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
}
}
@@ -104,7 +455,7 @@ const docTemplate = `{
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
}
}
@@ -127,7 +478,7 @@ const docTemplate = `{
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
}
}
@@ -161,7 +512,7 @@ const docTemplate = `{
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
},
{
"type": "object",
@@ -177,7 +528,7 @@ const docTemplate = `{
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
}
}
@@ -202,7 +553,7 @@ const docTemplate = `{
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
},
{
"type": "object",
@@ -210,7 +561,7 @@ const docTemplate = `{
"data": {
"allOf": [
{
"$ref": "#/definitions/handler.PaginatedData"
"$ref": "#/definitions/response.PaginatedData"
},
{
"type": "object",
@@ -252,7 +603,7 @@ const docTemplate = `{
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
},
{
"type": "object",
@@ -293,13 +644,13 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
},
"408": {
"description": "Request Timeout",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
}
}
@@ -307,7 +658,129 @@ const docTemplate = `{
}
},
"definitions": {
"handler.PaginatedData": {
"handler.quotaPayload": {
"type": "object",
"required": [
"business_line_id",
"cpu_milli",
"instance_limit",
"memory_mi",
"storage_gi",
"target_id"
],
"properties": {
"business_line_id": {
"type": "integer"
},
"cpu_milli": {
"type": "integer"
},
"instance_limit": {
"type": "integer"
},
"memory_mi": {
"type": "integer"
},
"storage_gi": {
"type": "integer"
},
"target_id": {
"type": "integer"
}
}
},
"handler.targetPayload": {
"type": "object",
"required": [
"awx_inventory_id",
"awx_template_id",
"name",
"target_type"
],
"properties": {
"awx_inventory_id": {
"type": "integer"
},
"awx_template_id": {
"type": "integer"
},
"metadata": {
"type": "object",
"additionalProperties": {}
},
"name": {
"type": "string"
},
"target_type": {
"type": "string"
}
}
},
"model.DeploymentTarget": {
"type": "object",
"properties": {
"awx_inventory_id": {
"type": "integer"
},
"awx_template_id": {
"type": "integer"
},
"created_at": {
"type": "string"
},
"enabled": {
"type": "boolean"
},
"id": {
"type": "integer"
},
"metadata": {
"type": "string"
},
"name": {
"type": "string"
},
"target_type": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"model.ResourceQuota": {
"type": "object",
"properties": {
"business_line_id": {
"type": "integer"
},
"cpu_milli": {
"type": "integer"
},
"created_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"instance_limit": {
"type": "integer"
},
"memory_mi": {
"type": "integer"
},
"storage_gi": {
"type": "integer"
},
"target_id": {
"type": "integer"
},
"updated_at": {
"type": "string"
}
}
},
"response.PaginatedData": {
"type": "object",
"properties": {
"items": {},
@@ -316,25 +789,58 @@ const docTemplate = `{
}
}
},
"handler.Response": {
"response.Response": {
"type": "object",
"properties": {
"code": {
"description": "业务错误码,0 表示成功",
"type": "integer"
},
"data": {
"description": "响应数据,成功时返回"
},
"data": {},
"details": {
"description": "错误详情,失败时返回",
"type": "string"
},
"message": {
"description": "响应消息",
"type": "string"
}
}
},
"service.MySQLDeliveryInput": {
"type": "object",
"required": [
"business_line_id",
"cpu_milli",
"instance_name",
"memory_mi",
"namespace",
"storage_gi",
"target_id"
],
"properties": {
"business_line_id": {
"type": "integer"
},
"cpu_milli": {
"type": "integer"
},
"instance_name": {
"type": "string"
},
"memory_mi": {
"type": "integer"
},
"mysql_version": {
"type": "string"
},
"namespace": {
"type": "string"
},
"storage_gi": {
"type": "integer"
},
"target_id": {
"type": "integer"
}
}
}
},
"securityDefinitions": {
+525 -19
View File
@@ -17,6 +17,357 @@
},
"basePath": "/api/v1",
"paths": {
"/auth/api/v1/delivery/mysql": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "创建一个 MySQL 交付任务,调度器会自动分配主机、调用 AWX 执行部署",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "提交 MySQL 一键交付",
"parameters": [
{
"type": "string",
"description": "幂等键(防重复提交,最长 128 字符)",
"name": "Idempotency-Key",
"in": "header",
"required": true
},
{
"description": "交付参数",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/service.MySQLDeliveryInput"
}
}
],
"responses": {
"200": {
"description": "幂等重放(相同 Idempotency-Key 已存在)",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"202": {
"description": "任务已创建",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"400": {
"description": "参数错误",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/auth/api/v1/delivery/quotas": {
"put": {
"security": [
{
"BearerAuth": []
}
],
"description": "管理员为指定业务线 + 部署目标设置资源配额",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "创建或更新资源配额",
"parameters": [
{
"description": "配额参数",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handler.quotaPayload"
}
}
],
"responses": {
"200": {
"description": "配额已更新",
"schema": {
"$ref": "#/definitions/model.ResourceQuota"
}
},
"400": {
"description": "参数错误",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/auth/api/v1/delivery/targets": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "返回所有已启用的部署目标(如 k8s 集群、主机池)",
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "获取可用部署目标",
"responses": {
"200": {
"description": "items: 部署目标数组",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"500": {
"description": "内部错误",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
},
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "管理员创建新的部署目标(目前仅支持 k8s 类型)",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "创建部署目标",
"parameters": [
{
"description": "目标配置",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/handler.targetPayload"
}
}
],
"responses": {
"201": {
"description": "目标已创建",
"schema": {
"$ref": "#/definitions/model.DeploymentTarget"
}
},
"400": {
"description": "参数错误",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"409": {
"description": "名称冲突",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/auth/api/v1/delivery/tasks": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "返回当前用户可见的交付任务列表(管理员可见全部)",
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "获取交付任务列表",
"parameters": [
{
"type": "integer",
"description": "业务线 ID 过滤",
"name": "business_line_id",
"in": "query"
}
],
"responses": {
"200": {
"description": "items: 任务数组",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/auth/api/v1/delivery/tasks/{id}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "返回指定任务的详细信息及事件流",
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "获取交付任务详情",
"parameters": [
{
"type": "string",
"description": "任务 ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "task + events",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"404": {
"description": "任务不存在",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/auth/api/v1/delivery/tasks/{id}/cancel": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "取消一个正在执行或等待中的交付任务",
"produces": [
"application/json"
],
"tags": [
"delivery"
],
"summary": "取消交付任务",
"parameters": [
{
"type": "string",
"description": "任务 ID",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "ok: true",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"401": {
"description": "未授权",
"schema": {
"type": "object",
"additionalProperties": true
}
},
"409": {
"description": "无法取消(状态冲突)",
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
},
"/ping": {
"get": {
"description": "检查服务器是否正常运行",
@@ -36,7 +387,7 @@
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
},
{
"type": "object",
@@ -74,7 +425,7 @@
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
}
}
@@ -97,7 +448,7 @@
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
}
}
@@ -120,7 +471,7 @@
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
}
}
@@ -154,7 +505,7 @@
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
},
{
"type": "object",
@@ -170,7 +521,7 @@
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
}
}
@@ -195,7 +546,7 @@
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
},
{
"type": "object",
@@ -203,7 +554,7 @@
"data": {
"allOf": [
{
"$ref": "#/definitions/handler.PaginatedData"
"$ref": "#/definitions/response.PaginatedData"
},
{
"type": "object",
@@ -245,7 +596,7 @@
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
},
{
"type": "object",
@@ -286,13 +637,13 @@
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
},
"408": {
"description": "Request Timeout",
"schema": {
"$ref": "#/definitions/handler.Response"
"$ref": "#/definitions/response.Response"
}
}
}
@@ -300,7 +651,129 @@
}
},
"definitions": {
"handler.PaginatedData": {
"handler.quotaPayload": {
"type": "object",
"required": [
"business_line_id",
"cpu_milli",
"instance_limit",
"memory_mi",
"storage_gi",
"target_id"
],
"properties": {
"business_line_id": {
"type": "integer"
},
"cpu_milli": {
"type": "integer"
},
"instance_limit": {
"type": "integer"
},
"memory_mi": {
"type": "integer"
},
"storage_gi": {
"type": "integer"
},
"target_id": {
"type": "integer"
}
}
},
"handler.targetPayload": {
"type": "object",
"required": [
"awx_inventory_id",
"awx_template_id",
"name",
"target_type"
],
"properties": {
"awx_inventory_id": {
"type": "integer"
},
"awx_template_id": {
"type": "integer"
},
"metadata": {
"type": "object",
"additionalProperties": {}
},
"name": {
"type": "string"
},
"target_type": {
"type": "string"
}
}
},
"model.DeploymentTarget": {
"type": "object",
"properties": {
"awx_inventory_id": {
"type": "integer"
},
"awx_template_id": {
"type": "integer"
},
"created_at": {
"type": "string"
},
"enabled": {
"type": "boolean"
},
"id": {
"type": "integer"
},
"metadata": {
"type": "string"
},
"name": {
"type": "string"
},
"target_type": {
"type": "string"
},
"updated_at": {
"type": "string"
}
}
},
"model.ResourceQuota": {
"type": "object",
"properties": {
"business_line_id": {
"type": "integer"
},
"cpu_milli": {
"type": "integer"
},
"created_at": {
"type": "string"
},
"id": {
"type": "integer"
},
"instance_limit": {
"type": "integer"
},
"memory_mi": {
"type": "integer"
},
"storage_gi": {
"type": "integer"
},
"target_id": {
"type": "integer"
},
"updated_at": {
"type": "string"
}
}
},
"response.PaginatedData": {
"type": "object",
"properties": {
"items": {},
@@ -309,25 +782,58 @@
}
}
},
"handler.Response": {
"response.Response": {
"type": "object",
"properties": {
"code": {
"description": "业务错误码,0 表示成功",
"type": "integer"
},
"data": {
"description": "响应数据,成功时返回"
},
"data": {},
"details": {
"description": "错误详情,失败时返回",
"type": "string"
},
"message": {
"description": "响应消息",
"type": "string"
}
}
},
"service.MySQLDeliveryInput": {
"type": "object",
"required": [
"business_line_id",
"cpu_milli",
"instance_name",
"memory_mi",
"namespace",
"storage_gi",
"target_id"
],
"properties": {
"business_line_id": {
"type": "integer"
},
"cpu_milli": {
"type": "integer"
},
"instance_name": {
"type": "string"
},
"memory_mi": {
"type": "integer"
},
"mysql_version": {
"type": "string"
},
"namespace": {
"type": "string"
},
"storage_gi": {
"type": "integer"
},
"target_id": {
"type": "integer"
}
}
}
},
"securityDefinitions": {
+352 -18
View File
@@ -1,25 +1,131 @@
basePath: /api/v1
definitions:
handler.PaginatedData:
handler.quotaPayload:
properties:
business_line_id:
type: integer
cpu_milli:
type: integer
instance_limit:
type: integer
memory_mi:
type: integer
storage_gi:
type: integer
target_id:
type: integer
required:
- business_line_id
- cpu_milli
- instance_limit
- memory_mi
- storage_gi
- target_id
type: object
handler.targetPayload:
properties:
awx_inventory_id:
type: integer
awx_template_id:
type: integer
metadata:
additionalProperties: {}
type: object
name:
type: string
target_type:
type: string
required:
- awx_inventory_id
- awx_template_id
- name
- target_type
type: object
model.DeploymentTarget:
properties:
awx_inventory_id:
type: integer
awx_template_id:
type: integer
created_at:
type: string
enabled:
type: boolean
id:
type: integer
metadata:
type: string
name:
type: string
target_type:
type: string
updated_at:
type: string
type: object
model.ResourceQuota:
properties:
business_line_id:
type: integer
cpu_milli:
type: integer
created_at:
type: string
id:
type: integer
instance_limit:
type: integer
memory_mi:
type: integer
storage_gi:
type: integer
target_id:
type: integer
updated_at:
type: string
type: object
response.PaginatedData:
properties:
items: {}
total:
type: integer
type: object
handler.Response:
response.Response:
properties:
code:
description: 业务错误码,0 表示成功
type: integer
data:
description: 响应数据,成功时返回
data: {}
details:
description: 错误详情,失败时返回
type: string
message:
description: 响应消息
type: string
type: object
service.MySQLDeliveryInput:
properties:
business_line_id:
type: integer
cpu_milli:
type: integer
instance_name:
type: string
memory_mi:
type: integer
mysql_version:
type: string
namespace:
type: string
storage_gi:
type: integer
target_id:
type: integer
required:
- business_line_id
- cpu_milli
- instance_name
- memory_mi
- namespace
- storage_gi
- target_id
type: object
info:
contact:
email: support@swagger.io
@@ -33,6 +139,234 @@ info:
title: xinfra API
version: "1.0"
paths:
/auth/api/v1/delivery/mysql:
post:
consumes:
- application/json
description: 创建一个 MySQL 交付任务,调度器会自动分配主机、调用 AWX 执行部署
parameters:
- description: 幂等键(防重复提交,最长 128 字符)
in: header
name: Idempotency-Key
required: true
type: string
- description: 交付参数
in: body
name: body
required: true
schema:
$ref: '#/definitions/service.MySQLDeliveryInput'
produces:
- application/json
responses:
"200":
description: 幂等重放(相同 Idempotency-Key 已存在)
schema:
additionalProperties: true
type: object
"202":
description: 任务已创建
schema:
additionalProperties: true
type: object
"400":
description: 参数错误
schema:
additionalProperties: true
type: object
"401":
description: 未授权
schema:
additionalProperties: true
type: object
security:
- BearerAuth: []
summary: 提交 MySQL 一键交付
tags:
- delivery
/auth/api/v1/delivery/quotas:
put:
consumes:
- application/json
description: 管理员为指定业务线 + 部署目标设置资源配额
parameters:
- description: 配额参数
in: body
name: body
required: true
schema:
$ref: '#/definitions/handler.quotaPayload'
produces:
- application/json
responses:
"200":
description: 配额已更新
schema:
$ref: '#/definitions/model.ResourceQuota'
"400":
description: 参数错误
schema:
additionalProperties: true
type: object
"401":
description: 未授权
schema:
additionalProperties: true
type: object
security:
- BearerAuth: []
summary: 创建或更新资源配额
tags:
- delivery
/auth/api/v1/delivery/targets:
get:
description: 返回所有已启用的部署目标(如 k8s 集群、主机池)
produces:
- application/json
responses:
"200":
description: 'items: 部署目标数组'
schema:
additionalProperties: true
type: object
"500":
description: 内部错误
schema:
additionalProperties: true
type: object
security:
- BearerAuth: []
summary: 获取可用部署目标
tags:
- delivery
post:
consumes:
- application/json
description: 管理员创建新的部署目标(目前仅支持 k8s 类型)
parameters:
- description: 目标配置
in: body
name: body
required: true
schema:
$ref: '#/definitions/handler.targetPayload'
produces:
- application/json
responses:
"201":
description: 目标已创建
schema:
$ref: '#/definitions/model.DeploymentTarget'
"400":
description: 参数错误
schema:
additionalProperties: true
type: object
"401":
description: 未授权
schema:
additionalProperties: true
type: object
"409":
description: 名称冲突
schema:
additionalProperties: true
type: object
security:
- BearerAuth: []
summary: 创建部署目标
tags:
- delivery
/auth/api/v1/delivery/tasks:
get:
description: 返回当前用户可见的交付任务列表(管理员可见全部)
parameters:
- description: 业务线 ID 过滤
in: query
name: business_line_id
type: integer
produces:
- application/json
responses:
"200":
description: 'items: 任务数组'
schema:
additionalProperties: true
type: object
"401":
description: 未授权
schema:
additionalProperties: true
type: object
security:
- BearerAuth: []
summary: 获取交付任务列表
tags:
- delivery
/auth/api/v1/delivery/tasks/{id}:
get:
description: 返回指定任务的详细信息及事件流
parameters:
- description: 任务 ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: task + events
schema:
additionalProperties: true
type: object
"401":
description: 未授权
schema:
additionalProperties: true
type: object
"404":
description: 任务不存在
schema:
additionalProperties: true
type: object
security:
- BearerAuth: []
summary: 获取交付任务详情
tags:
- delivery
/auth/api/v1/delivery/tasks/{id}/cancel:
post:
description: 取消一个正在执行或等待中的交付任务
parameters:
- description: 任务 ID
in: path
name: id
required: true
type: string
produces:
- application/json
responses:
"200":
description: 'ok: true'
schema:
additionalProperties: true
type: object
"401":
description: 未授权
schema:
additionalProperties: true
type: object
"409":
description: 无法取消(状态冲突)
schema:
additionalProperties: true
type: object
security:
- BearerAuth: []
summary: 取消交付任务
tags:
- delivery
/ping:
get:
consumes:
@@ -45,7 +379,7 @@ paths:
description: OK
schema:
allOf:
- $ref: '#/definitions/handler.Response'
- $ref: '#/definitions/response.Response'
- properties:
data:
properties:
@@ -67,7 +401,7 @@ paths:
"401":
description: Unauthorized
schema:
$ref: '#/definitions/handler.Response'
$ref: '#/definitions/response.Response'
summary: 测试 401 错误
tags:
- 测试
@@ -82,7 +416,7 @@ paths:
"403":
description: Forbidden
schema:
$ref: '#/definitions/handler.Response'
$ref: '#/definitions/response.Response'
summary: 测试 403 错误
tags:
- 测试
@@ -97,7 +431,7 @@ paths:
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/handler.Response'
$ref: '#/definitions/response.Response'
summary: 测试 500 错误
tags:
- 测试
@@ -119,7 +453,7 @@ paths:
description: OK
schema:
allOf:
- $ref: '#/definitions/handler.Response'
- $ref: '#/definitions/response.Response'
- properties:
details:
type: string
@@ -127,7 +461,7 @@ paths:
"400":
description: Bad Request
schema:
$ref: '#/definitions/handler.Response'
$ref: '#/definitions/response.Response'
summary: 测试业务错误响应
tags:
- 测试
@@ -143,11 +477,11 @@ paths:
description: OK
schema:
allOf:
- $ref: '#/definitions/handler.Response'
- $ref: '#/definitions/response.Response'
- properties:
data:
allOf:
- $ref: '#/definitions/handler.PaginatedData'
- $ref: '#/definitions/response.PaginatedData'
- properties:
items:
items:
@@ -170,7 +504,7 @@ paths:
description: OK
schema:
allOf:
- $ref: '#/definitions/handler.Response'
- $ref: '#/definitions/response.Response'
- properties:
data:
properties:
@@ -194,11 +528,11 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/handler.Response'
$ref: '#/definitions/response.Response'
"408":
description: Request Timeout
schema:
$ref: '#/definitions/handler.Response'
$ref: '#/definitions/response.Response'
summary: 测试超时响应
tags:
- 测试
+5
View File
@@ -20,6 +20,7 @@ require (
github.com/bytedance/sonic v1.14.0 // indirect
github.com/bytedance/sonic/loader v0.3.0 // indirect
github.com/cloudwego/base64x v0.1.6 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
@@ -45,8 +46,11 @@ require (
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/quic-go/qpack v0.5.1 // indirect
github.com/quic-go/quic-go v0.54.0 // indirect
github.com/russross/blackfriday/v2 v2.0.1 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.0 // indirect
github.com/urfave/cli/v2 v2.3.0 // indirect
go.uber.org/mock v0.5.0 // indirect
golang.org/x/arch v0.20.0 // indirect
golang.org/x/crypto v0.54.0 // indirect
@@ -58,4 +62,5 @@ require (
golang.org/x/tools v0.47.0 // indirect
google.golang.org/protobuf v1.36.9 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
+12
View File
@@ -1,5 +1,6 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
@@ -12,6 +13,8 @@ github.com/bytedance/sonic/loader v0.3.0 h1:dskwH8edlzNMctoruo8FPTJDF3vLtDT0sXZw
github.com/bytedance/sonic/loader v0.3.0/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -91,6 +94,10 @@ github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -111,6 +118,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
@@ -167,6 +176,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -177,3 +187,5 @@ gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg=
gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo=
gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4=
gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
+10 -10
View File
@@ -17,7 +17,7 @@ import (
// @Tags 系统
// @Accept json
// @Produce json
// @Success 200 {object} Response{data=object{time=string}}
// @Success 200 {object} response.Response{data=object{time=string}}
// @Router /ping [get]
func Ping(c *gin.Context) {
response.Success(c, gin.H{"time": time.Now().Format(time.RFC3339)})
@@ -29,7 +29,7 @@ func Ping(c *gin.Context) {
// @Tags 测试
// @Accept json
// @Produce json
// @Success 200 {object} Response{data=object{username=string,role=string}}
// @Success 200 {object} response.Response{data=object{username=string,role=string}}
// @Router /test/success [get]
func TestSuccess(c *gin.Context) {
response.Success(c, gin.H{
@@ -45,8 +45,8 @@ func TestSuccess(c *gin.Context) {
// @Accept json
// @Produce json
// @Param code path int true "业务错误码 (10001-10099: 认证相关, 20001-20099: 任务相关)"
// @Success 200 {object} Response{details=string}
// @Failure 400 {object} Response
// @Success 200 {object} response.Response{details=string}
// @Failure 400 {object} response.Response
// @Router /test/error/{code} [get]
func TestError(c *gin.Context) {
codeStr := c.Param("code")
@@ -65,7 +65,7 @@ func TestError(c *gin.Context) {
// @Tags 测试
// @Accept json
// @Produce json
// @Success 500 {object} Response
// @Success 500 {object} response.Response
// @Router /test/500 [get]
func Test500(c *gin.Context) {
response.InternalError(c, "模拟服务器内部错误")
@@ -77,7 +77,7 @@ func Test500(c *gin.Context) {
// @Tags 测试
// @Accept json
// @Produce json
// @Success 401 {object} Response
// @Success 401 {object} response.Response
// @Router /test/401 [get]
func Test401(c *gin.Context) {
response.Unauthorized(c, "模拟 Token 过期")
@@ -89,7 +89,7 @@ func Test401(c *gin.Context) {
// @Tags 测试
// @Accept json
// @Produce json
// @Success 403 {object} Response
// @Success 403 {object} response.Response
// @Router /test/403 [get]
func Test403(c *gin.Context) {
response.Forbidden(c, "模拟无权限")
@@ -101,8 +101,8 @@ func Test403(c *gin.Context) {
// @Tags 测试
// @Accept json
// @Produce json
// @Success 200 {object} Response
// @Failure 408 {object} Response
// @Success 200 {object} response.Response
// @Failure 408 {object} response.Response
// @Router /test/timeout [get]
func TestTimeout(c *gin.Context) {
time.Sleep(15 * time.Second)
@@ -115,7 +115,7 @@ func TestTimeout(c *gin.Context) {
// @Tags 测试
// @Accept json
// @Produce json
// @Success 200 {object} Response{data=PaginatedData{items=[]object}}
// @Success 200 {object} response.Response{data=response.PaginatedData{items=[]object}}
// @Router /test/paginated [get]
func TestPaginated(c *gin.Context) {
items := []gin.H{