mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
Pengjingzhao ospp v2 (#23309)
* feat(mcp-server): 增加mcclient sdk适配器结构体以及对应的认证方法 * feat(mcp-server): 增加资源查询的sdk适配器方法 * feat(mcp-server): 增加资源操作的sdk适配器方法 * feat(mcp-server): 增加区域资源查询工具 * feat(mcp-server): 增加网络资源查询工具 * feat(mcp-server): 增加镜像资源查询工具 * feat(mcp-server): 增加虚拟机资源查询工具 * feat(mcp-server): 增加vpc资源查询工具 * feat(mcp-server): 增加存储资源查询工具 * feat(mcp-server): 增加套餐资源查询工具 * feat(mcp-server): 增加虚拟机创建工具 * feat(mcp-server): 增加虚拟机监控工具 * feat(mcp-server): 增加虚拟机操作工具,包括启动、重启、停止、重置密码和删除 * optimize(mcp-server): 增加工具函数接口定义 * feat(mcp-server): 增加工具函数所使用的结构体模型 * feat(mcp-server): 新增工具统一注册中心 * feat(mcp-server): 增加mcp服务中心 * feat(mcp-server): 增加统一配置中心 * feat(mcp-server): 增加服务启动主入口 * doc(mcp-server): 增加mcp-server相关的说明,安装和使用文档 * fix(mcp-server): 更正文档位置以及补充图片 * refactor(mcp-server): 修正了service以及配置解析的逻辑 * refactor(mcp-server): 将日志打印相关代码改成使用log * feat(mcp-server): 增加mcclient sdk适配器结构体以及对应的认证方法 * feat(mcp-server): 增加资源查询的sdk适配器方法 * feat(mcp-server): 增加资源操作的sdk适配器方法 * feat(mcp-server): 增加区域资源查询工具 * feat(mcp-server): 增加网络资源查询工具 * feat(mcp-server): 增加镜像资源查询工具 * feat(mcp-server): 增加虚拟机资源查询工具 * feat(mcp-server): 增加vpc资源查询工具 * feat(mcp-server): 增加存储资源查询工具 * feat(mcp-server): 增加套餐资源查询工具 * feat(mcp-server): 增加虚拟机创建工具 * feat(mcp-server): 增加虚拟机监控工具 * feat(mcp-server): 增加虚拟机操作工具,包括启动、重启、停止、重置密码和删除 * optimize(mcp-server): 增加工具函数接口定义 * feat(mcp-server): 增加工具函数所使用的结构体模型 * feat(mcp-server): 新增工具统一注册中心 * feat(mcp-server): 增加mcp服务中心 * feat(mcp-server): 增加统一配置中心 * feat(mcp-server): 增加服务启动主入口 * doc(mcp-server): 增加mcp-server相关的说明,安装和使用文档 * fix(mcp-server): 更正文档位置以及补充图片 * refactor(mcp-server): 修正了service以及配置解析的逻辑 * refactor(mcp-server): 将日志打印相关代码改成使用log * fix(mcp-server): 修复依赖导入以及缺失等问题 * refactor(mcp-server): 复用common_options * fix: 修复配置结构体字段重复的问题 * doc(mcp-server): 更正文档错误 * style(mcp-server): 格式化import顺序 * style(mcp-server): 格式化import导入 * style(mcp-server): 规范import语句 * doc(mcp-server): 给目录生成doc文件 --------- Co-authored-by: 屈轩 <qu_xuan@icloud.com>
This commit is contained in:
192
pkg/mcp-server/tools/cloudpods_regions_tool.go
Normal file
192
pkg/mcp-server/tools/cloudpods_regions_tool.go
Normal file
@@ -0,0 +1,192 @@
|
||||
// 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"
|
||||
)
|
||||
|
||||
// CloudpodsRegionsTool 是用于查询 Cloudpods 区域列表的工具
|
||||
type CloudpodsRegionsTool struct {
|
||||
// adapter 用于与 Cloudpods API 进行交互
|
||||
adapter *adapters.CloudpodsAdapter
|
||||
}
|
||||
|
||||
// NewCloudpodsRegionsTool 创建一个新的 Cloudpods 区域查询工具
|
||||
// adapter: 用于与 Cloudpods API 进行交互的适配器
|
||||
// 返回值: 指向新创建的 CloudpodsRegionsTool 实例的指针
|
||||
func NewCloudpodsRegionsTool(adapter *adapters.CloudpodsAdapter) *CloudpodsRegionsTool {
|
||||
return &CloudpodsRegionsTool{
|
||||
adapter: adapter,
|
||||
}
|
||||
}
|
||||
|
||||
// GetTool 返回 MCP 工具定义,用于查询 Cloudpods 区域列表
|
||||
// 该工具用于查询Cloudpods中的区域列表,获取所有可用的云区域信息
|
||||
// 支持的参数包括:
|
||||
// - limit: 返回结果数量限制,默认为50
|
||||
// - offset: 返回结果偏移量,默认为0
|
||||
// - search: 搜索关键词,可以按区域名称搜索
|
||||
// - provider: 云平台提供商,例如:aws、azure、aliyun等
|
||||
// - ak: 用户登录cloudpods后获取的access key
|
||||
// - sk: 用户登录cloudpods后获取的secret key
|
||||
func (c *CloudpodsRegionsTool) GetTool() mcp.Tool {
|
||||
return mcp.NewTool(
|
||||
"cloudpods_list_regions",
|
||||
mcp.WithDescription("查询Cloudpods区域列表,获取所有可用的云区域信息"),
|
||||
mcp.WithString("limit", mcp.Description("返回结果数量限制,默认为50")),
|
||||
mcp.WithString("offset", mcp.Description("返回结果偏移量,默认为0")),
|
||||
mcp.WithString("search", mcp.Description("搜索关键词,可以按区域名称搜索")),
|
||||
mcp.WithString("provider", mcp.Description("云平台提供商,例如:aws、azure、aliyun等")),
|
||||
mcp.WithString("ak", mcp.Description("用户登录cloudpods后获取的access key")),
|
||||
mcp.WithString("sk", mcp.Description("用户登录cloudpods后获取的secret key")),
|
||||
)
|
||||
}
|
||||
|
||||
// Handle 处理查询 Cloudpods 区域列表的请求
|
||||
// ctx: 控制请求生命周期的上下文
|
||||
// req: 包含查询参数的请求对象
|
||||
// 返回值: 包含查询结果的工具结果对象或错误信息
|
||||
func (c *CloudpodsRegionsTool) Handle(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
// 设置默认查询限制为50
|
||||
limit := 50
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// 获取搜索关键词和提供商参数
|
||||
search := req.GetString("search", "")
|
||||
provider := req.GetString("provider", "")
|
||||
|
||||
// 获取访问凭证
|
||||
ak := req.GetString("ak", "")
|
||||
sk := req.GetString("sk", "")
|
||||
|
||||
// 调用适配器获取区域列表
|
||||
regionsResponse, err := c.adapter.ListCloudRegions(ctx, limit, offset, search, provider, ak, sk)
|
||||
if err != nil {
|
||||
log.Errorf("Fail to query region: %s", err)
|
||||
return nil, fmt.Errorf("fail to query region: %w", err)
|
||||
}
|
||||
|
||||
// 格式化查询结果
|
||||
formattedResult := c.formatRegionsResult(regionsResponse, limit, offset, search, provider)
|
||||
|
||||
// 将结果序列化为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
|
||||
}
|
||||
|
||||
// formatRegionsResult 格式化区域列表查询结果
|
||||
// response: 从适配器获取的原始区域数据
|
||||
// limit: 查询限制数量
|
||||
// offset: 查询偏移量
|
||||
// search: 搜索关键词
|
||||
// provider: 云平台提供商
|
||||
// 返回值: 格式化后的区域列表数据,包含查询信息、区域列表和摘要信息
|
||||
func (c *CloudpodsRegionsTool) formatRegionsResult(response *models.CloudregionListResponse, limit, offset int, search, provider string) map[string]interface{} {
|
||||
// 初始化结果结构,包含查询信息和区域列表
|
||||
formatted := map[string]interface{}{
|
||||
"query_info": map[string]interface{}{
|
||||
"limit": limit,
|
||||
"offset": offset,
|
||||
"search": search,
|
||||
"provider": provider,
|
||||
"total": response.Total,
|
||||
"count": len(response.Cloudregions),
|
||||
},
|
||||
"cloudregions": make([]map[string]interface{}, 0, len(response.Cloudregions)),
|
||||
}
|
||||
|
||||
// 遍历原始区域数据,构造每个区域的详细信息
|
||||
for _, region := range response.Cloudregions {
|
||||
// 构造单个区域信息
|
||||
regionInfo := map[string]interface{}{
|
||||
"id": region.Id,
|
||||
"name": region.Name,
|
||||
"description": region.Description,
|
||||
"provider": region.Provider,
|
||||
"cloud_env": region.CloudEnv,
|
||||
"environment": region.Environment,
|
||||
"city": region.City,
|
||||
"country_code": region.CountryCode,
|
||||
"latitude": region.Latitude,
|
||||
"longitude": region.Longitude,
|
||||
"status": region.Status,
|
||||
"enabled": region.Enabled,
|
||||
"external_id": region.ExternalId,
|
||||
"guest_count": region.GuestCount,
|
||||
"guest_increment_count": region.GuestIncrementCount,
|
||||
"network_count": region.NetworkCount,
|
||||
"vpc_count": region.VpcCount,
|
||||
"zone_count": region.ZoneCount,
|
||||
"progress": region.Progress,
|
||||
"source": region.Source,
|
||||
"can_delete": region.CanDelete,
|
||||
"can_update": region.CanUpdate,
|
||||
"is_emulated": region.IsEmulated,
|
||||
"metadata": region.Metadata,
|
||||
"created_at": region.CreatedAt,
|
||||
"updated_at": region.UpdatedAt,
|
||||
"imported_at": region.ImportedAt,
|
||||
}
|
||||
// 将区域信息添加到结果数组中
|
||||
formatted["cloudregions"] = append(formatted["cloudregions"].([]map[string]interface{}), regionInfo)
|
||||
}
|
||||
|
||||
// 构造摘要信息
|
||||
formatted["summary"] = map[string]interface{}{
|
||||
"total_cloudregions": response.Total,
|
||||
"returned_count": len(response.Cloudregions),
|
||||
"has_more": response.Total > int64(offset+len(response.Cloudregions)),
|
||||
"next_offset": offset + len(response.Cloudregions),
|
||||
}
|
||||
|
||||
// 返回格式化后的结果
|
||||
return formatted
|
||||
}
|
||||
|
||||
// GetName 返回工具名称
|
||||
// 返回值: 工具名称字符串,用于唯一标识该工具
|
||||
func (c *CloudpodsRegionsTool) GetName() string {
|
||||
return "cloudpods_list_regions"
|
||||
}
|
||||
Reference in New Issue
Block a user