Files
cloudpods/pkg/mcp-server/tools/cloudpods_networks_tool.go

266 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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"
)
// CloudpodsNetworksTool 是一个用于查询 Cloudpods 网络列表的工具
type CloudpodsNetworksTool struct {
// adapter 用于与 Cloudpods API 进行交互
adapter *adapters.CloudpodsAdapter
}
// NewCloudpodsNetworksTool 创建一个新的 CloudpodsNetworksTool 实例
// adapter: 用于与 Cloudpods API 进行交互的适配器
// 返回值: 指向新创建的 CloudpodsNetworksTool 实例的指针
func NewCloudpodsNetworksTool(adapter *adapters.CloudpodsAdapter) *CloudpodsNetworksTool {
return &CloudpodsNetworksTool{
adapter: adapter,
}
}
// GetTool 定义并返回网络列表查询工具的元数据
// 该工具用于查询Cloudpods中的IP子网列表获取网络配置信息
// 支持的参数包括:
// - limit: 返回结果数量限制默认为20
// - offset: 返回结果偏移量默认为0
// - search: 搜索关键词,可以按网络名称搜索
// - vpc_id: 过滤指定VPC的网络资源
// - ak: 用户登录cloudpods后获取的access key
// - sk: 用户登录cloudpods后获取的secret key
func (c *CloudpodsNetworksTool) GetTool() mcp.Tool {
return mcp.NewTool(
"cloudpods_list_networks",
mcp.WithDescription("查询Cloudpods IP子网列表获取网络配置信息"),
mcp.WithString("limit", mcp.Description("返回结果数量限制默认为20")),
mcp.WithString("offset", mcp.Description("返回结果偏移量默认为0")),
mcp.WithString("search", mcp.Description("搜索关键词,可以按网络名称搜索")),
mcp.WithString("vpc_id", mcp.Description("过滤指定VPC的网络资源")),
mcp.WithString("ak", mcp.Description("用户登录cloudpods后获取的access key")),
mcp.WithString("sk", mcp.Description("用户登录cloudpods后获取的secret key")),
)
}
// Handle 处理网络列表查询请求
// ctx: 控制请求生命周期的上下文
// req: 包含查询参数的请求对象
// 返回值: 包含查询结果的工具结果对象或错误信息
func (c *CloudpodsNetworksTool) Handle(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
// 设置默认查询限制为20
limit := 20
if limitStr := req.GetString("limit", ""); limitStr != "" {
// 解析limit参数如果解析成功且大于0则使用解析后的值
if parsedLimit, err := strconv.Atoi(limitStr); err == nil && parsedLimit > 0 {
limit = parsedLimit
}
}
// 设置默认偏移量为0
offset := 0
if offsetStr := req.GetString("offset", ""); offsetStr != "" {
// 解析offset参数如果解析成功且大于等于0则使用解析后的值
if parsedOffset, err := strconv.Atoi(offsetStr); err == nil && parsedOffset >= 0 {
offset = parsedOffset
}
}
// 获取搜索关键词和VPC ID参数
search := req.GetString("search", "")
vpcId := req.GetString("vpc_id", "")
// 获取访问凭证
ak := req.GetString("ak", "")
sk := req.GetString("sk", "")
// 调用适配器获取网络列表
networksResponse, err := c.adapter.ListNetworks(ctx, limit, offset, search, vpcId, ak, sk)
if err != nil {
log.Errorf("Fail to query network: %s", err)
return nil, fmt.Errorf("fail to query network: %w", err)
}
// 格式化查询结果
formattedResult := c.formatNetworksResult(networksResponse, limit, offset, search, vpcId)
// 将结果序列化为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 返回工具的名称标识符
// 返回值: 工具名称字符串,用于唯一标识该工具
func (c *CloudpodsNetworksTool) GetName() string {
return "cloudpods_list_networks"
}
// formatNetworksResult 格式化网络列表查询结果
// response: 从适配器获取的原始网络数据
// limit: 查询限制数量
// offset: 查询偏移量
// search: 搜索关键词
// vpcId: VPC ID过滤条件
// 返回值: 格式化后的网络列表数据,包含查询信息、网络列表和摘要信息
func (c *CloudpodsNetworksTool) formatNetworksResult(response *models.NetworkListResponse, limit, offset int, search, vpcId string) map[string]interface{} {
// 初始化结果结构,包含查询信息和网络列表
formatted := map[string]interface{}{
"query_info": map[string]interface{}{
"limit": limit,
"offset": offset,
"search": search,
"vpc_id": vpcId,
"total": response.Total,
"count": len(response.Networks),
},
"networks": make([]map[string]interface{}, 0, len(response.Networks)),
}
// 遍历原始网络数据,构造每个网络的详细信息
for _, network := range response.Networks {
// 构造单个网络信息
networkInfo := map[string]interface{}{
"id": network.Id,
"name": network.Name,
"description": network.Description,
"status": network.Status,
"guest_ip_start": network.GuestIpStart,
"guest_ip_end": network.GuestIpEnd,
"guest_ip_mask": network.GuestIpMask,
"guest_gateway": network.GuestGateway,
"guest_dns": network.GuestDns,
"guest_dhcp": network.GuestDhcp,
"guest_ntp": network.GuestNtp,
"guest_domain": network.GuestDomain,
"guest_ip6_start": network.GuestIp6Start,
"guest_ip6_end": network.GuestIp6End,
"guest_ip6_mask": network.GuestIp6Mask,
"guest_gateway6": network.GuestGateway6,
"guest_dns6": network.GuestDns6,
"guest_domain6": network.GuestDomain6,
"vpc": network.Vpc,
"vpc_id": network.VpcId,
"vpc_ext_id": network.VpcExtId,
"wire": network.Wire,
"wire_id": network.WireId,
"zone": network.Zone,
"zone_id": network.ZoneId,
"cloudregion": network.Cloudregion,
"cloudregion_id": network.CloudregionId,
"region": network.Region,
"region_id": network.RegionId,
"provider": network.Provider,
"brand": network.Brand,
"cloud_env": network.CloudEnv,
"environment": network.Environment,
"external_id": network.ExternalId,
"account": network.Account,
"account_id": network.AccountId,
"account_status": network.AccountStatus,
"account_health_status": network.AccountHealthStatus,
"manager": network.Manager,
"manager_id": network.ManagerId,
"manager_domain": network.ManagerDomain,
"manager_domain_id": network.ManagerDomainId,
"manager_project": network.ManagerProject,
"manager_project_id": network.ManagerProjectId,
"server_type": network.ServerType,
"alloc_policy": network.AllocPolicy,
"vlan_id": network.VlanId,
"bgp_type": network.BgpType,
"is_auto_alloc": network.IsAutoAlloc,
"is_classic": network.IsClassic,
"is_default_vpc": network.IsDefaultVpc,
"is_public": network.IsPublic,
"is_system": network.IsSystem,
"is_emulated": network.IsEmulated,
"exit": network.Exit,
"freezed": network.Freezed,
"pending_deleted": network.PendingDeleted,
"pending_deleted_at": network.PendingDeletedAt,
"ports": network.Ports,
"ports_used": network.PortsUsed,
"ports6_used": network.Ports6Used,
"total": network.Total,
"total6": network.Total6,
"vnics": network.Vnics,
"vnics4": network.Vnics4,
"vnics6": network.Vnics6,
"bm_vnics": network.BmVnics,
"bm_reused_vnics": network.BmReusedVnics,
"eip_vnics": network.EipVnics,
"group_vnics": network.GroupVnics,
"lb_vnics": network.LbVnics,
"nat_vnics": network.NatVnics,
"networkinterface_vnics": network.NetworkinterfaceVnics,
"rds_vnics": network.RdsVnics,
"reserve_vnics4": network.ReserveVnics4,
"reserve_vnics6": network.ReserveVnics6,
"routes": network.Routes,
"schedtags": network.Schedtags,
"additional_wires": network.AdditionalWires,
"shared_domains": network.SharedDomains,
"shared_projects": network.SharedProjects,
"project": network.Project,
"project_id": network.ProjectId,
"project_domain": network.ProjectDomain,
"project_metadata": network.ProjectMetadata,
"project_src": network.ProjectSrc,
"tenant": network.Tenant,
"tenant_id": network.TenantId,
"domain_id": network.DomainId,
"public_scope": network.PublicScope,
"public_src": network.PublicSrc,
"source": network.Source,
"progress": network.Progress,
"can_delete": network.CanDelete,
"can_update": network.CanUpdate,
"metadata": network.Metadata,
"created_at": network.CreatedAt,
"updated_at": network.UpdatedAt,
"imported_at": network.ImportedAt,
}
// 将网络信息添加到结果数组中
formatted["networks"] = append(formatted["networks"].([]map[string]interface{}), networkInfo)
}
// 构造摘要信息
formatted["summary"] = map[string]interface{}{
"total_networks": response.Total,
"returned_count": len(response.Networks),
"has_more": response.Total > int64(offset+len(response.Networks)),
"next_offset": offset + len(response.Networks),
}
// 返回格式化后的结果
return formatted
}