刚更新

This commit is contained in:
zhanggangyong
2026-01-06 09:08:32 +00:00
parent 6e9d4df6ce
commit 369d9951d2
@@ -83,75 +83,75 @@ class AvailablePlatformAgentsResponse(BaseModel):
class PlatformAgentApplicationCreate(BaseModel):
"""创建平台 Agent 申请"""
template_name: str = Field(..., description="平台 Agent 模板名称")
requested_pod_quota: int = Field(..., ge=1, le=100, description="申请的 Pod 配额")
templateName: str = Field(..., description="平台 Agent 模板名称")
requestedPodQuota: int = Field(..., ge=1, le=100, description="申请的 Pod 配额")
reason: str = Field(..., min_length=10, max_length=500, description="申请理由")
class PlatformAgentApplicationResponse(BaseModel):
"""平台 Agent 申请响应"""
id: uuid.UUID
channel_id: uuid.UUID
template_name: str
requested_pod_quota: int
channelId: uuid.UUID
templateName: str
requestedPodQuota: int
reason: str
status: str
approved_pod_quota: Optional[int] = None
review_reason: Optional[str] = None
reviewed_at: Optional[datetime] = None
created_at: datetime
approvedPodQuota: Optional[int] = None
reviewReason: Optional[str] = None
reviewedAt: Optional[datetime] = None
createdAt: datetime
class ApplicationReviewRequest(BaseModel):
"""审批申请请求"""
action: str = Field(..., pattern="^(approve|reject)$", description="审批动作")
pod_quota: Optional[int] = Field(None, ge=0, description="批准的 Pod 配额(approve 时必填)")
review_reason: Optional[str] = Field(None, max_length=500, description="审批意见")
podQuota: Optional[int] = Field(None, ge=0, description="批准的 Pod 配额(approve 时必填)")
reviewReason: Optional[str] = Field(None, max_length=500, description="审批意见")
class TenantPlatformAgentAllocation(BaseModel):
"""分配平台 Agent 给租户"""
template_name: str = Field(..., description="平台 Agent 模板名称")
pod_quota: int = Field(..., ge=1, le=50, description="分配的 Pod 配额")
templateName: str = Field(..., description="平台 Agent 模板名称")
podQuota: int = Field(..., ge=1, le=50, description="分配的 Pod 配额")
description: Optional[str] = None
class PlatformAgentQuotaResponse(BaseModel):
"""平台 Agent 配额响应"""
id: uuid.UUID
target_id: uuid.UUID
target_type: str
template_name: str
pod_quota: int
pod_used: int
allocated_at: datetime
targetId: uuid.UUID
targetType: str
templateName: str
podQuota: int
podUsed: int
allocatedAt: datetime
class PlatformAgentTemplateConfigRequest(BaseModel):
"""平台 Agent 模板配置请求(管理员配置)"""
cpu_request: Optional[str] = Field(None, description="CPU 请求量,如 100m")
cpu_limit: Optional[str] = Field(None, description="CPU 限制量,如 500m")
memory_request: Optional[str] = Field(None, description="内存请求量,如 128Mi")
memory_limit: Optional[str] = Field(None, description="内存限制量,如 512Mi")
max_pods: Optional[int] = Field(None, ge=0, description="最大 Pod 数量")
is_enabled: Optional[bool] = Field(True, description="是否启用")
display_name: Optional[str] = Field(None, max_length=200, description="显示名称")
cpuRequest: Optional[str] = Field(None, description="CPU 请求量,如 100m")
cpuLimit: Optional[str] = Field(None, description="CPU 限制量,如 500m")
memoryRequest: Optional[str] = Field(None, description="内存请求量,如 128Mi")
memoryLimit: Optional[str] = Field(None, description="内存限制量,如 512Mi")
maxPods: Optional[int] = Field(None, ge=0, description="最大 Pod 数量")
isEnabled: Optional[bool] = Field(True, description="是否启用")
displayName: Optional[str] = Field(None, max_length=200, description="显示名称")
description: Optional[str] = Field(None, description="描述")
class PlatformAgentTemplateConfigResponse(BaseModel):
"""平台 Agent 模板配置响应"""
template_name: str
cpu_request: Optional[str] = None
cpu_limit: Optional[str] = None
memory_request: Optional[str] = None
memory_limit: Optional[str] = None
max_pods: int = 0
is_enabled: bool = True
display_name: Optional[str] = None
templateName: str
cpuRequest: Optional[str] = None
cpuLimit: Optional[str] = None
memoryRequest: Optional[str] = None
memoryLimit: Optional[str] = None
maxPods: int = 0
isEnabled: bool = True
displayName: Optional[str] = None
description: Optional[str] = None
configured_at: Optional[datetime] = None
configured_by: Optional[uuid.UUID] = None
configuredAt: Optional[datetime] = None
configuredBy: Optional[uuid.UUID] = None
class UsePlatformAgentRequest(BaseModel):
@@ -164,8 +164,8 @@ class PlatformAgentInstanceResponse(BaseModel):
name: str
template: str
status: str
pod_ip: Optional[str] = None
created_at: datetime
podIp: Optional[str] = None
createdAt: datetime
# ==================== 渠道路由 ====================
@@ -260,8 +260,8 @@ async def create_platform_agent_application(
templates = await client.list_platform_templates()
template_names = [t.template for t in templates]
if request.template_name not in template_names:
raise HTTPException(status_code=400, detail=f"模板 {request.template_name} 不存在")
if request.templateName not in template_names:
raise HTTPException(status_code=400, detail=f"模板 {request.templateName} 不存在")
# 检查是否已有待审批的申请
existing = await db.execute(
@@ -269,7 +269,7 @@ async def create_platform_agent_application(
and_(
ResourceApplication.channel_id == uuid.UUID(channel_id),
ResourceApplication.resource_type == "platform_agent",
ResourceApplication.template_name == request.template_name,
ResourceApplication.template_name == request.templateName,
ResourceApplication.status == "pending"
)
)
@@ -281,8 +281,8 @@ async def create_platform_agent_application(
application = ResourceApplication(
channel_id=uuid.UUID(channel_id),
resource_type="platform_agent",
template_name=request.template_name,
requested_pod_quota=request.requested_pod_quota,
template_name=request.templateName,
requested_pod_quota=request.requestedPodQuota,
reason=request.reason,
status="pending"
)
@@ -294,17 +294,17 @@ async def create_platform_agent_application(
"创建平台 Agent 申请",
application_id=str(application.id),
channel_id=channel_id,
template=request.template_name
template=request.templateName
)
return PlatformAgentApplicationResponse(
id=application.id,
channel_id=application.channel_id,
template_name=application.template_name,
requested_pod_quota=application.requested_pod_quota,
channelId=application.channel_id,
templateName=application.template_name,
requestedPodQuota=application.requested_pod_quota,
reason=application.reason,
status=application.status,
created_at=application.created_at
createdAt=application.created_at
)
except HTTPException:
@@ -347,15 +347,15 @@ async def list_channel_platform_agent_applications(
return [
PlatformAgentApplicationResponse(
id=app.id,
channel_id=app.channel_id,
template_name=app.template_name,
requested_pod_quota=app.requested_pod_quota,
channelId=app.channel_id,
templateName=app.template_name,
requestedPodQuota=app.requested_pod_quota,
reason=app.reason,
status=app.status,
approved_pod_quota=app.approved_pod_quota,
review_reason=app.review_reason,
reviewed_at=app.reviewed_at,
created_at=app.created_at
approvedPodQuota=app.approved_pod_quota,
reviewReason=app.review_reason,
reviewedAt=app.reviewed_at,
createdAt=app.created_at
)
for app in applications
]
@@ -389,12 +389,12 @@ async def list_channel_platform_agent_quotas(
return [
PlatformAgentQuotaResponse(
id=q.id,
target_id=q.target_id,
target_type=q.target_type,
template_name=q.template_name,
pod_quota=q.pod_quota,
pod_used=q.pod_used,
allocated_at=q.allocated_at
targetId=q.target_id,
targetType=q.target_type,
templateName=q.template_name,
podQuota=q.pod_quota,
podUsed=q.pod_used,
allocatedAt=q.allocated_at
)
for q in quotas
]
@@ -436,27 +436,27 @@ async def allocate_platform_agent_to_tenant(
and_(
PlatformAgentQuota.target_id == channel_uuid,
PlatformAgentQuota.target_type == "channel",
PlatformAgentQuota.template_name == request.template_name
PlatformAgentQuota.template_name == request.templateName
)
)
)
channel_quota = channel_quota_result.scalar_one_or_none()
if not channel_quota:
raise HTTPException(status_code=400, detail=f"渠道没有 {request.template_name} 的配额")
raise HTTPException(status_code=400, detail=f"渠道没有 {request.templateName} 的配额")
# 计算已分配给租户的总配额
allocated_result = await db.execute(
select(PlatformAgentQuota).where(
and_(
PlatformAgentQuota.target_type == "tenant",
PlatformAgentQuota.template_name == request.template_name
PlatformAgentQuota.template_name == request.templateName
)
)
)
total_allocated = sum(q.pod_quota for q in allocated_result.scalars().all())
if total_allocated + request.pod_quota > channel_quota.pod_quota:
if total_allocated + request.podQuota > channel_quota.pod_quota:
raise HTTPException(
status_code=400,
detail=f"配额不足,渠道配额: {channel_quota.pod_quota},已分配: {total_allocated}"
@@ -468,7 +468,7 @@ async def allocate_platform_agent_to_tenant(
and_(
PlatformAgentQuota.target_id == tenant_uuid,
PlatformAgentQuota.target_type == "tenant",
PlatformAgentQuota.template_name == request.template_name
PlatformAgentQuota.template_name == request.templateName
)
)
)
@@ -476,7 +476,7 @@ async def allocate_platform_agent_to_tenant(
if existing_quota:
# 更新现有配额
existing_quota.pod_quota = request.pod_quota
existing_quota.pod_quota = request.podQuota
existing_quota.allocated_at = datetime.utcnow()
quota = existing_quota
else:
@@ -484,8 +484,8 @@ async def allocate_platform_agent_to_tenant(
quota = PlatformAgentQuota(
target_id=tenant_uuid,
target_type="tenant",
template_name=request.template_name,
pod_quota=request.pod_quota,
template_name=request.templateName,
pod_quota=request.podQuota,
pod_used=0,
allocated_by=uuid.UUID(_get_user_id(current_user))
)
@@ -496,7 +496,7 @@ async def allocate_platform_agent_to_tenant(
client = get_agent_manager_client()
# 构建 Pod 名称
pod_name = f"{request.template_name}-{tenant_id[:8]}"
pod_name = f"{request.templateName}-{tenant_id[:8]}"
# 创建 Agent 配置
agent_config = AgentConfig(
@@ -508,7 +508,7 @@ async def allocate_platform_agent_to_tenant(
# 调用 Agent Manager 创建 Pod
result = await client.create_agent(
name=pod_name,
template=request.template_name,
template=request.templateName,
config=agent_config
)
@@ -519,7 +519,7 @@ async def allocate_platform_agent_to_tenant(
agent = Agent(
name=pod_name,
type="platform",
template=request.template_name,
template=request.templateName,
pod_name=result.name,
k8s_namespace=result.namespace,
k8s_status=result.status,
@@ -532,7 +532,7 @@ async def allocate_platform_agent_to_tenant(
logger.info(
"平台 Agent 分配成功",
tenant_id=tenant_id,
template=request.template_name,
template=request.templateName,
pod_name=result.name
)
@@ -549,12 +549,12 @@ async def allocate_platform_agent_to_tenant(
return PlatformAgentQuotaResponse(
id=quota.id,
target_id=quota.target_id,
target_type=quota.target_type,
template_name=quota.template_name,
pod_quota=quota.pod_quota,
pod_used=quota.pod_used,
allocated_at=quota.allocated_at
targetId=quota.target_id,
targetType=quota.target_type,
templateName=quota.template_name,
podQuota=quota.pod_quota,
podUsed=quota.pod_used,
allocatedAt=quota.allocated_at
)
@@ -588,15 +588,15 @@ async def list_all_platform_agent_applications(
return [
PlatformAgentApplicationResponse(
id=app.id,
channel_id=app.channel_id,
template_name=app.template_name,
requested_pod_quota=app.requested_pod_quota,
channelId=app.channel_id,
templateName=app.template_name,
requestedPodQuota=app.requested_pod_quota,
reason=app.reason,
status=app.status,
approved_pod_quota=app.approved_pod_quota,
review_reason=app.review_reason,
reviewed_at=app.reviewed_at,
created_at=app.created_at
approvedPodQuota=app.approved_pod_quota,
reviewReason=app.review_reason,
reviewedAt=app.reviewed_at,
createdAt=app.created_at
)
for app in applications
]
@@ -635,12 +635,12 @@ async def review_platform_agent_application(
# 处理审批
if request.action == "approve":
if request.pod_quota is None or request.pod_quota <= 0:
if request.podQuota is None or request.podQuota <= 0:
raise HTTPException(status_code=400, detail="批准时必须指定 Pod 配额")
application.status = "approved"
application.approved_pod_quota = request.pod_quota
application.review_reason = request.review_reason
application.approved_pod_quota = request.podQuota
application.review_reason = request.reviewReason
application.reviewed_by = uuid.UUID(_get_user_id(current_user))
application.reviewed_at = datetime.utcnow()
@@ -657,13 +657,13 @@ async def review_platform_agent_application(
existing_quota = existing_quota_result.scalar_one_or_none()
if existing_quota:
existing_quota.pod_quota += request.pod_quota
existing_quota.pod_quota += request.podQuota
else:
quota = PlatformAgentQuota(
target_id=application.channel_id,
target_type="channel",
template_name=application.template_name,
pod_quota=request.pod_quota,
pod_quota=request.podQuota,
pod_used=0,
allocated_by=uuid.UUID(_get_user_id(current_user))
)
@@ -674,12 +674,12 @@ async def review_platform_agent_application(
application_id=application_id,
channel_id=str(application.channel_id),
template=application.template_name,
pod_quota=request.pod_quota
pod_quota=request.podQuota
)
else: # reject
application.status = "rejected"
application.review_reason = request.review_reason
application.review_reason = request.reviewReason
application.reviewed_by = uuid.UUID(_get_user_id(current_user))
application.reviewed_at = datetime.utcnow()
@@ -687,7 +687,7 @@ async def review_platform_agent_application(
"审批拒绝",
application_id=application_id,
channel_id=str(application.channel_id),
reason=request.review_reason
reason=request.reviewReason
)
await db.commit()
@@ -727,18 +727,18 @@ async def list_platform_agent_templates_admin(
template_list.append({
"name": t.template,
"port": t.port,
"env_info": t.env_info,
"is_configured": config is not None,
"envInfo": t.env_info,
"isConfigured": config is not None,
"config": {
"cpu_request": config.cpu_request if config else None,
"cpu_limit": config.cpu_limit if config else None,
"memory_request": config.memory_request if config else None,
"memory_limit": config.memory_limit if config else None,
"max_pods": config.max_pods if config else 0,
"is_enabled": config.is_enabled if config else False,
"display_name": config.display_name if config else None,
"cpuRequest": config.cpu_request if config else None,
"cpuLimit": config.cpu_limit if config else None,
"memoryRequest": config.memory_request if config else None,
"memoryLimit": config.memory_limit if config else None,
"maxPods": config.max_pods if config else 0,
"isEnabled": config.is_enabled if config else False,
"displayName": config.display_name if config else None,
"description": config.description if config else None,
"configured_at": config.configured_at.isoformat() if config and config.configured_at else None,
"configuredAt": config.configured_at.isoformat() if config and config.configured_at else None,
} if config else None
})
@@ -785,20 +785,20 @@ async def configure_platform_agent_template(
if config:
# 更新现有配置
if request.cpu_request is not None:
config.cpu_request = request.cpu_request
if request.cpu_limit is not None:
config.cpu_limit = request.cpu_limit
if request.memory_request is not None:
config.memory_request = request.memory_request
if request.memory_limit is not None:
config.memory_limit = request.memory_limit
if request.max_pods is not None:
config.max_pods = request.max_pods
if request.is_enabled is not None:
config.is_enabled = request.is_enabled
if request.display_name is not None:
config.display_name = request.display_name
if request.cpuRequest is not None:
config.cpu_request = request.cpuRequest
if request.cpuLimit is not None:
config.cpu_limit = request.cpuLimit
if request.memoryRequest is not None:
config.memory_request = request.memoryRequest
if request.memoryLimit is not None:
config.memory_limit = request.memoryLimit
if request.maxPods is not None:
config.max_pods = request.maxPods
if request.isEnabled is not None:
config.is_enabled = request.isEnabled
if request.displayName is not None:
config.display_name = request.displayName
if request.description is not None:
config.description = request.description
config.configured_by = uuid.UUID(_get_user_id(current_user))
@@ -807,13 +807,13 @@ async def configure_platform_agent_template(
# 创建新配置
config = PlatformAgentTemplateConfig(
template_name=template_name,
cpu_request=request.cpu_request,
cpu_limit=request.cpu_limit,
memory_request=request.memory_request,
memory_limit=request.memory_limit,
max_pods=request.max_pods or 0,
is_enabled=request.is_enabled if request.is_enabled is not None else True,
display_name=request.display_name,
cpu_request=request.cpuRequest,
cpu_limit=request.cpuLimit,
memory_request=request.memoryRequest,
memory_limit=request.memoryLimit,
max_pods=request.maxPods or 0,
is_enabled=request.isEnabled if request.isEnabled is not None else True,
display_name=request.displayName,
description=request.description,
configured_by=uuid.UUID(_get_user_id(current_user)),
configured_at=datetime.utcnow()
@@ -830,17 +830,17 @@ async def configure_platform_agent_template(
)
return PlatformAgentTemplateConfigResponse(
template_name=config.template_name,
cpu_request=config.cpu_request,
cpu_limit=config.cpu_limit,
memory_request=config.memory_request,
memory_limit=config.memory_limit,
max_pods=config.max_pods or 0,
is_enabled=config.is_enabled,
display_name=config.display_name,
templateName=config.template_name,
cpuRequest=config.cpu_request,
cpuLimit=config.cpu_limit,
memoryRequest=config.memory_request,
memoryLimit=config.memory_limit,
maxPods=config.max_pods or 0,
isEnabled=config.is_enabled,
displayName=config.display_name,
description=config.description,
configured_at=config.configured_at,
configured_by=config.configured_by
configuredAt=config.configured_at,
configuredBy=config.configured_by
)
except HTTPException:
@@ -876,17 +876,17 @@ async def get_platform_agent_template_config(
raise HTTPException(status_code=404, detail=f"模板 {template_name} 尚未配置")
return PlatformAgentTemplateConfigResponse(
template_name=config.template_name,
cpu_request=config.cpu_request,
cpu_limit=config.cpu_limit,
memory_request=config.memory_request,
memory_limit=config.memory_limit,
max_pods=config.max_pods or 0,
is_enabled=config.is_enabled,
display_name=config.display_name,
templateName=config.template_name,
cpuRequest=config.cpu_request,
cpuLimit=config.cpu_limit,
memoryRequest=config.memory_request,
memoryLimit=config.memory_limit,
maxPods=config.max_pods or 0,
isEnabled=config.is_enabled,
displayName=config.display_name,
description=config.description,
configured_at=config.configured_at,
configured_by=config.configured_by
configuredAt=config.configured_at,
configuredBy=config.configured_by
)
@@ -918,12 +918,12 @@ async def list_user_platform_agents(
return [
PlatformAgentQuotaResponse(
id=q.id,
target_id=q.target_id,
target_type=q.target_type,
template_name=q.template_name,
pod_quota=q.pod_quota,
pod_used=q.pod_used,
allocated_at=q.allocated_at
targetId=q.target_id,
targetType=q.target_type,
templateName=q.template_name,
podQuota=q.pod_quota,
podUsed=q.pod_used,
allocatedAt=q.allocated_at
)
for q in quotas
]
@@ -956,8 +956,8 @@ async def list_user_platform_agent_instances(
name=a.pod_name or a.name,
template=a.template,
status=a.k8s_status or "Unknown",
pod_ip=a.pod_ip,
created_at=a.created_at
podIp=a.pod_ip,
createdAt=a.created_at
)
for a in agents
]
@@ -1071,18 +1071,18 @@ async def get_user_platform_agent_quota(
quota_usage = []
for q in quotas:
quota_usage.append({
"template_name": q.template_name,
"pod_quota": q.pod_quota,
"pod_used": q.pod_used,
"pod_available": q.pod_quota - q.pod_used,
"usage_percent": round((q.pod_used / q.pod_quota * 100) if q.pod_quota > 0 else 0, 2)
"templateName": q.template_name,
"podQuota": q.pod_quota,
"podUsed": q.pod_used,
"podAvailable": q.pod_quota - q.pod_used,
"usagePercent": round((q.pod_used / q.pod_quota * 100) if q.pod_quota > 0 else 0, 2)
})
return {
"user_id": user_id,
"userId": user_id,
"quotas": quota_usage,
"total_quota": sum(q.pod_quota for q in quotas),
"total_used": sum(q.pod_used for q in quotas)
"totalQuota": sum(q.pod_quota for q in quotas),
"totalUsed": sum(q.pod_used for q in quotas)
}
@@ -1121,9 +1121,9 @@ async def get_platform_agent_status(
"name": agent_name,
"template": agent.template,
"status": status.status,
"pod_ip": status.pod_ip,
"node_name": status.node_name,
"created_at": status.created_at,
"podIp": status.pod_ip,
"nodeName": status.node_name,
"createdAt": status.created_at,
"labels": status.labels
}
except AgentManagerError as e:
@@ -1133,9 +1133,9 @@ async def get_platform_agent_status(
"name": agent_name,
"template": agent.template,
"status": agent.k8s_status or "Unknown",
"pod_ip": agent.pod_ip,
"node_name": None,
"created_at": agent.created_at.isoformat() if agent.created_at else None,
"podIp": agent.pod_ip,
"nodeName": None,
"createdAt": agent.created_at.isoformat() if agent.created_at else None,
"labels": {}
}
raise HTTPException(status_code=e.status_code, detail=e.detail)