mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-21 06:09:39 +08:00
240 lines
8.3 KiB
Go
240 lines
8.3 KiB
Go
// Copyright 2019 Yunion
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package tools
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"github.com/mark3labs/mcp-go/mcp"
|
|
|
|
"yunion.io/x/log"
|
|
|
|
"yunion.io/x/onecloud/pkg/mcp-server/adapters"
|
|
"yunion.io/x/onecloud/pkg/mcp-server/models"
|
|
)
|
|
|
|
// CloudpodsVPCsTool 用于查询Cloudpods VPC列表的工具
|
|
//
|
|
// 字段:
|
|
// - adapter: 用于与Cloudpods API进行交互的适配器
|
|
type CloudpodsVPCsTool struct {
|
|
adapter *adapters.CloudpodsAdapter
|
|
}
|
|
|
|
// NewCloudpodsVPCsTool 创建CloudpodsVPCsTool实例
|
|
//
|
|
// 参数:
|
|
// - adapter: 用于与Cloudpods API交互的适配器
|
|
//
|
|
// 返回值:
|
|
// - *CloudpodsVPCsTool: CloudpodsVPCsTool实例指针
|
|
func NewCloudpodsVPCsTool(adapter *adapters.CloudpodsAdapter) *CloudpodsVPCsTool {
|
|
return &CloudpodsVPCsTool{
|
|
adapter: adapter,
|
|
}
|
|
}
|
|
|
|
// GetTool 定义并返回查询VPC列表工具的元数据
|
|
//
|
|
// 工具用途:
|
|
//
|
|
// 查询Cloudpods VPC列表,获取虚拟私有网络信息
|
|
//
|
|
// 参数说明:
|
|
// - limit: 返回结果数量限制,默认为20
|
|
// - offset: 返回结果偏移量,默认为0
|
|
// - search: 搜索关键词,可以按VPC名称搜索
|
|
// - cloudregion_id: 过滤指定云区域的VPC资源
|
|
// - ak: 用户登录cloudpods后获取的access key
|
|
// - sk: 用户登录cloudpods后获取的secret key
|
|
func (c *CloudpodsVPCsTool) GetTool() mcp.Tool {
|
|
return mcp.NewTool(
|
|
"cloudpods_list_vpcs",
|
|
mcp.WithDescription("查询Cloudpods VPC列表,获取虚拟私有网络信息"),
|
|
mcp.WithString("limit", mcp.Description("返回结果数量限制,默认为20")),
|
|
mcp.WithString("offset", mcp.Description("返回结果偏移量,默认为0")),
|
|
mcp.WithString("search", mcp.Description("搜索关键词,可以按VPC名称搜索")),
|
|
mcp.WithString("cloudregion_id", mcp.Description("过滤指定云区域的VPC资源")),
|
|
mcp.WithString("ak", mcp.Description("用户登录cloudpods后获取的access key")),
|
|
mcp.WithString("sk", mcp.Description("用户登录cloudpods后获取的secret key")),
|
|
)
|
|
}
|
|
|
|
// Handle 处理查询VPC列表的请求
|
|
//
|
|
// 参数:
|
|
// - ctx: 控制生命周期的上下文
|
|
// - req: 包含查询参数的请求对象
|
|
//
|
|
// 返回值:
|
|
// - *mcp.CallToolResult: 包含VPC列表的响应对象
|
|
// - error: 可能的错误信息
|
|
func (c *CloudpodsVPCsTool) Handle(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
// 获取可选参数:返回结果数量限制,如果指定则转换为整数
|
|
limit := 20
|
|
if limitStr := req.GetString("limit", ""); limitStr != "" {
|
|
if parsedLimit, err := strconv.Atoi(limitStr); err == nil && parsedLimit > 0 {
|
|
limit = parsedLimit
|
|
}
|
|
}
|
|
|
|
// 获取可选参数:结果偏移量,如果指定则转换为整数
|
|
offset := 0
|
|
if offsetStr := req.GetString("offset", ""); offsetStr != "" {
|
|
if parsedOffset, err := strconv.Atoi(offsetStr); err == nil && parsedOffset >= 0 {
|
|
offset = parsedOffset
|
|
}
|
|
}
|
|
|
|
// 获取可选参数:搜索关键词
|
|
search := req.GetString("search", "")
|
|
// 获取可选参数:云区域ID
|
|
cloudRegionID := req.GetString("cloudregion_id", "")
|
|
|
|
// 获取可选参数:访问凭证
|
|
ak := req.GetString("ak", "")
|
|
sk := req.GetString("sk", "")
|
|
|
|
// 调用适配器查询VPC列表
|
|
vpcsResponse, err := c.adapter.ListVPCs(limit, offset, search, cloudRegionID, ak, sk)
|
|
if err != nil {
|
|
log.Errorf("Fail to query vpc: %s", err)
|
|
return nil, fmt.Errorf("fail to query vpc: %w", err)
|
|
}
|
|
|
|
// 格式化查询结果
|
|
formattedResult := c.formatVPCsResult(vpcsResponse, limit, offset, search, cloudRegionID)
|
|
|
|
// 将结果序列化为JSON格式
|
|
resultJSON, err := json.MarshalIndent(formattedResult, "", " ")
|
|
if err != nil {
|
|
log.Errorf("Fail to serialize result: %s", err)
|
|
return nil, fmt.Errorf("fail to serialize result: %w", err)
|
|
}
|
|
|
|
return mcp.NewToolResultText(string(resultJSON)), nil
|
|
}
|
|
|
|
// GetName 返回工具的名称标识符
|
|
//
|
|
// 返回值:
|
|
// - string: 工具名称字符串,用于唯一标识该工具
|
|
func (c *CloudpodsVPCsTool) GetName() string {
|
|
return "cloudpods_list_vpcs"
|
|
}
|
|
|
|
// formatVPCsResult 格式化VPC列表的响应结果
|
|
//
|
|
// 参数:
|
|
// - response: 原始响应数据
|
|
// - limit: 查询限制
|
|
// - offset: 查询偏移量
|
|
// - search: 搜索关键词
|
|
// - cloudRegionID: 云区域ID
|
|
//
|
|
// 返回值:
|
|
// - map[string]interface{}: 包含VPC列表的格式化结果
|
|
func (c *CloudpodsVPCsTool) formatVPCsResult(response *models.VpcListResponse, limit, offset int, search, cloudRegionID string) map[string]interface{} {
|
|
// 初始化格式化结果结构
|
|
formatted := map[string]interface{}{
|
|
"query_info": map[string]interface{}{
|
|
"limit": limit,
|
|
"offset": offset,
|
|
"search": search,
|
|
"cloudregion_id": cloudRegionID,
|
|
"total": response.Total,
|
|
"count": len(response.Vpcs),
|
|
},
|
|
"vpcs": make([]map[string]interface{}, 0, len(response.Vpcs)),
|
|
}
|
|
|
|
// 遍历VPC列表,构造每个VPC的详细信息
|
|
for _, vpc := range response.Vpcs {
|
|
vpcInfo := map[string]interface{}{
|
|
"id": vpc.Id,
|
|
"name": vpc.Name,
|
|
"description": vpc.Description,
|
|
"cidr_block": vpc.CidrBlock,
|
|
"cidr_block6": vpc.CidrBlock6,
|
|
"status": vpc.Status,
|
|
"enabled": vpc.Enabled,
|
|
"is_default": vpc.IsDefault,
|
|
"is_public": vpc.IsPublic,
|
|
"provider": vpc.Provider,
|
|
"brand": vpc.Brand,
|
|
"cloud_env": vpc.CloudEnv,
|
|
"environment": vpc.Environment,
|
|
"cloudregion": vpc.Cloudregion,
|
|
"cloudregion_id": vpc.CloudregionId,
|
|
"region": vpc.Region,
|
|
"region_id": vpc.RegionId,
|
|
"external_id": vpc.ExternalId,
|
|
"external_access_mode": vpc.ExternalAccessMode,
|
|
"globalvpc": vpc.Globalvpc,
|
|
"globalvpc_id": vpc.GlobalvpcId,
|
|
"account": vpc.Account,
|
|
"account_id": vpc.AccountId,
|
|
"account_status": vpc.AccountStatus,
|
|
"account_health_status": vpc.AccountHealthStatus,
|
|
"manager": vpc.Manager,
|
|
"manager_id": vpc.ManagerId,
|
|
"manager_domain": vpc.ManagerDomain,
|
|
"manager_domain_id": vpc.ManagerDomainId,
|
|
"manager_project": vpc.ManagerProject,
|
|
"manager_project_id": vpc.ManagerProjectId,
|
|
"network_count": vpc.NetworkCount,
|
|
"wire_count": vpc.WireCount,
|
|
"dns_zone_count": vpc.DnsZoneCount,
|
|
"natgateway_count": vpc.NatgatewayCount,
|
|
"routetable_count": vpc.RoutetableCount,
|
|
"accept_vpc_peer_count": vpc.AcceptVpcPeerCount,
|
|
"request_vpc_peer_count": vpc.RequestVpcPeerCount,
|
|
"direct": vpc.Direct,
|
|
"domain_id": vpc.DomainId,
|
|
"domain_src": vpc.DomainSrc,
|
|
"project_domain": vpc.ProjectDomain,
|
|
"public_scope": vpc.PublicScope,
|
|
"public_src": vpc.PublicSrc,
|
|
"region_ext_id": vpc.RegionExtId,
|
|
"region_external_id": vpc.RegionExternalId,
|
|
"source": vpc.Source,
|
|
"progress": vpc.Progress,
|
|
"shared_domains": vpc.SharedDomains,
|
|
"shared_projects": vpc.SharedProjects,
|
|
"can_delete": vpc.CanDelete,
|
|
"can_update": vpc.CanUpdate,
|
|
"is_emulated": vpc.IsEmulated,
|
|
"metadata": vpc.Metadata,
|
|
"created_at": vpc.CreatedAt,
|
|
"updated_at": vpc.UpdatedAt,
|
|
"imported_at": vpc.ImportedAt,
|
|
}
|
|
formatted["vpcs"] = append(formatted["vpcs"].([]map[string]interface{}), vpcInfo)
|
|
}
|
|
|
|
// 构造摘要信息
|
|
formatted["summary"] = map[string]interface{}{
|
|
"total_vpcs": response.Total,
|
|
"returned_count": len(response.Vpcs),
|
|
"has_more": response.Total > int64(offset+len(response.Vpcs)),
|
|
"next_offset": offset + len(response.Vpcs),
|
|
}
|
|
|
|
return formatted
|
|
}
|