Files
cloudpods/pkg/mcp-server/adapters/resource_query_adapter.go
2026-07-17 00:26:47 +08:00

501 lines
15 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 adapters
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/mcclient/modules/compute"
"yunion.io/x/onecloud/pkg/mcclient/modules/image"
"yunion.io/x/onecloud/pkg/mcp-server/models"
)
// ListCloudRegions 查询 Cloudpods 中的区域列表
func (a CloudpodsAdapter) ListCloudRegions(ctx context.Context, limit int, offset int, search string, provider string, ak string, sk string) (*models.CloudregionListResponse, error) {
// 获取 Cloudpods 会话
session, err := a.getSession(ctx, ak, sk)
if err != nil {
return nil, err
}
// 构造查询参数
params := jsonutils.NewDict()
params.Set("scope", jsonutils.NewString("max"))
if limit > 0 {
// 设置查询结果数量限制
params.Set("limit", jsonutils.NewInt(int64(limit)))
}
if offset > 0 {
// 设置查询偏移量
params.Set("offset", jsonutils.NewInt(int64(offset)))
}
if search != "" {
// 设置搜索关键字
params.Set("search", jsonutils.NewString(search))
}
if provider != "" {
// 设置云提供商过滤条件
providers := jsonutils.NewArray()
providers.Add(jsonutils.NewString(provider))
params.Set("providers", providers)
}
// 调用 Cloudpods API 查询区域列表
result, err := compute.Cloudregions.List(session, params)
if err != nil {
return nil, err
}
// 构造响应数据
response := &models.CloudregionListResponse{
Limit: int64(limit),
Offset: int64(offset),
Cloudregions: make([]models.CloudregionDetails, 0),
Total: int64(result.Total),
}
// 遍历查询结果,将数据转换为响应格式
for _, data := range result.Data {
region := models.CloudregionDetails{}
if err := data.Unmarshal(&region); err != nil {
// 如果数据转换失败,记录警告日志并跳过该条数据
log.Warningf("Failed to unmarshal cloudregion details: %s", err)
continue
}
response.Cloudregions = append(response.Cloudregions, region)
}
return response, nil
}
// ListVPCs 查询 Cloudpods 中的 VPC 列表
func (a *CloudpodsAdapter) ListVPCs(ctx context.Context, limit int, offset int, search string, cloudregionId string, ak string, sk string) (*models.VpcListResponse, error) {
// 获取 Cloudpods 会话
session, err := a.getSession(ctx, ak, sk)
if err != nil {
return nil, err
}
// 构造查询参数
params := jsonutils.NewDict()
params.Set("scope", jsonutils.NewString("max"))
if limit > 0 {
// 设置查询结果数量限制
params.Set("limit", jsonutils.NewInt(int64(limit)))
}
if offset > 0 {
// 设置查询偏移量
params.Set("offset", jsonutils.NewInt(int64(offset)))
}
if search != "" {
// 设置搜索关键字
params.Set("search", jsonutils.NewString(search))
}
if cloudregionId != "" {
// 设置云区域 ID 过滤条件
cloudregionIds := jsonutils.NewArray()
cloudregionIds.Add(jsonutils.NewString(cloudregionId))
params.Set("cloudregion_id", cloudregionIds)
}
// 调用 Cloudpods API 查询 VPC 列表
result, err := compute.Vpcs.List(session, params)
if err != nil {
return nil, fmt.Errorf("failed to list vpcs: %w", err)
}
// 构造响应数据
response := &models.VpcListResponse{
Limit: int64(limit),
Offset: int64(offset),
Vpcs: make([]models.VpcDetails, 0),
Total: int64(result.Total),
}
// 遍历查询结果,将数据转换为响应格式
for _, data := range result.Data {
vpc := models.VpcDetails{}
if err := data.Unmarshal(&vpc); err != nil {
// 如果数据转换失败,记录警告日志并跳过该条数据
log.Warningf("Failed to unmarshal vpc details: %s", err)
continue
}
response.Vpcs = append(response.Vpcs, vpc)
}
return response, nil
}
// ListNetworks 查询 Cloudpods 中的网络列表
func (a *CloudpodsAdapter) ListNetworks(ctx context.Context, limit int, offset int, search string, vpcId string, ak string, sk string) (*models.NetworkListResponse, error) {
// 获取 Cloudpods 会话
session, err := a.getSession(ctx, ak, sk)
if err != nil {
return nil, err
}
// 构造查询参数
params := jsonutils.NewDict()
params.Set("scope", jsonutils.NewString("max"))
if limit > 0 {
// 设置查询结果数量限制
params.Set("limit", jsonutils.NewInt(int64(limit)))
}
if offset > 0 {
// 设置查询偏移量
params.Set("offset", jsonutils.NewInt(int64(offset)))
}
if search != "" {
// 设置搜索关键字
params.Set("search", jsonutils.NewString(search))
}
if vpcId != "" {
// 设置 VPC ID 过滤条件
//vpcIds := jsonutils.NewArray()
//vpcIds.Add(jsonutils.NewString(vpcId))
//params.Set("vpc_id", vpcIds)
params.Set("vpc_id", jsonutils.NewString(vpcId))
}
// 调用 Cloudpods API 查询网络列表
result, err := compute.Networks.List(session, params)
if err != nil {
return nil, fmt.Errorf("failed to list networks: %w", err)
}
// 构造响应数据
response := &models.NetworkListResponse{
Limit: int64(limit),
Offset: int64(offset),
Networks: make([]models.NetworkDetails, 0),
Total: int64(result.Total),
}
// 遍历查询结果,将数据转换为响应格式
for _, data := range result.Data {
network := models.NetworkDetails{}
if err := data.Unmarshal(&network); err != nil {
// 如果数据转换失败,记录警告日志并跳过该条数据
log.Warningf("Failed to unmarshal network details: %s", err)
continue
}
response.Networks = append(response.Networks, network)
}
return response, nil
}
// ListImages 查询 Cloudpods 中的镜像列表
func (a *CloudpodsAdapter) ListImages(ctx context.Context, limit int, offset int, search string, osTypes []string, ak string, sk string) (*models.ImageListResponse, error) {
// 获取 Cloudpods 会话
session, err := a.getSession(ctx, ak, sk)
if err != nil {
return nil, err
}
// 构造查询参数
params := jsonutils.NewDict()
params.Set("scope", jsonutils.NewString("max"))
if limit > 0 {
// 设置查询结果数量限制
params.Set("limit", jsonutils.NewInt(int64(limit)))
}
if offset > 0 {
// 设置查询偏移量
params.Set("offset", jsonutils.NewInt(int64(offset)))
}
if search != "" {
// 设置搜索关键字
params.Set("search", jsonutils.NewString(search))
}
if len(osTypes) > 0 {
// 设置操作系统类型过滤条件
osTypesArray := jsonutils.NewArray()
for _, osType := range osTypes {
osTypesArray.Add(jsonutils.NewString(osType))
}
params.Set("os_types", osTypesArray)
}
// 调用 Cloudpods API 查询镜像列表
result, err := image.Images.List(session, params)
if err != nil {
return nil, fmt.Errorf("failed to list images: %w", err)
}
// 构造响应数据
response := &models.ImageListResponse{
Limit: int64(limit),
Offset: int64(offset),
Images: make([]models.ImageDetails, 0),
Total: int64(result.Total),
}
// 遍历查询结果,将数据转换为响应格式
for _, data := range result.Data {
image := models.ImageDetails{}
if err := data.Unmarshal(&image); err != nil {
// 如果数据转换失败,记录警告日志并跳过该条数据
log.Warningf("Failed to unmarshal image details: %s", err)
continue
}
response.Images = append(response.Images, image)
}
return response, nil
}
// ListServerSkus 查询 Cloudpods 中的服务器规格列表
func (a *CloudpodsAdapter) ListServerSkus(ctx context.Context, limit int, offset int, search string, cloudregionIds []string, zoneIds []string, cpuCoreCount []string, memorySizeMB []string, providers []string, cpuArch []string, ak string, sk string) (*models.ServerSkuListResponse, error) {
// 获取 Cloudpods 会话
session, err := a.getSession(ctx, ak, sk)
if err != nil {
return nil, err
}
// 构造查询参数
params := jsonutils.NewDict()
params.Set("scope", jsonutils.NewString("max"))
if limit > 0 {
// 设置查询结果数量限制
params.Set("limit", jsonutils.NewInt(int64(limit)))
}
if offset > 0 {
// 设置查询偏移量
params.Set("offset", jsonutils.NewInt(int64(offset)))
}
if search != "" {
// 设置搜索关键字
params.Set("search", jsonutils.NewString(search))
}
if len(cloudregionIds) > 0 {
// 设置云区域 ID 过滤条件
cloudregionIdArray := jsonutils.NewArray()
for _, id := range cloudregionIds {
cloudregionIdArray.Add(jsonutils.NewString(id))
}
params.Set("cloudregion_id", cloudregionIdArray)
}
if len(zoneIds) > 0 {
// 设置可用区 ID 过滤条件
zoneIdArray := jsonutils.NewArray()
for _, id := range zoneIds {
zoneIdArray.Add(jsonutils.NewString(id))
}
params.Set("zone_ids", zoneIdArray)
}
if len(cpuCoreCount) > 0 {
// 设置 CPU 核心数过滤条件
cpuCoreArray := jsonutils.NewArray()
for _, count := range cpuCoreCount {
cpuCoreArray.Add(jsonutils.NewString(count))
}
params.Set("cpu_core_count", cpuCoreArray)
}
if len(memorySizeMB) > 0 {
// 设置内存大小过滤条件
memoryArray := jsonutils.NewArray()
for _, size := range memorySizeMB {
memoryArray.Add(jsonutils.NewString(size))
}
params.Set("memory_size_mb", memoryArray)
}
if len(providers) > 0 {
// 设置提供商过滤条件
providerArray := jsonutils.NewArray()
for _, provider := range providers {
providerArray.Add(jsonutils.NewString(provider))
}
params.Set("providers", providerArray)
}
if len(cpuArch) > 0 {
// 设置 CPU 架构过滤条件
cpuArchArray := jsonutils.NewArray()
for _, arch := range cpuArch {
cpuArchArray.Add(jsonutils.NewString(arch))
}
params.Set("cpu_arch", cpuArchArray)
}
// 调用 Cloudpods API 查询服务器规格列表
result, err := compute.ServerSkus.List(session, params)
if err != nil {
return nil, fmt.Errorf("failed to list server skus: %w", err)
}
// 构造响应数据
response := &models.ServerSkuListResponse{
Limit: int64(limit),
Offset: int64(offset),
Serverskus: make([]models.ServerSkuDetails, 0),
Total: int64(result.Total),
}
// 遍历查询结果,将数据转换为响应格式
for _, data := range result.Data {
sku := models.ServerSkuDetails{}
if err := data.Unmarshal(&sku); err != nil {
// 如果数据转换失败,记录警告日志并跳过该条数据
log.Warningf("Failed to unmarshal server sku details: %s", err)
continue
}
response.Serverskus = append(response.Serverskus, sku)
}
return response, nil
}
// ListStorages 查询 Cloudpods 中的存储列表
func (a *CloudpodsAdapter) ListStorages(ctx context.Context, limit int, offset int, search string, cloudregionIds []string, zoneIds []string, providers []string, storageTypes []string, hostId string, ak string, sk string) (*models.StorageListResponse, error) {
// 获取 Cloudpods 会话
session, err := a.getSession(ctx, ak, sk)
if err != nil {
return nil, err
}
// 构造查询参数
params := jsonutils.NewDict()
params.Set("scope", jsonutils.NewString("max"))
if limit > 0 {
// 设置查询结果数量限制
params.Set("limit", jsonutils.NewInt(int64(limit)))
}
if offset > 0 {
// 设置查询偏移量
params.Set("offset", jsonutils.NewInt(int64(offset)))
}
if search != "" {
// 设置搜索关键字
params.Set("search", jsonutils.NewString(search))
}
if len(cloudregionIds) > 0 {
// 设置云区域 ID 过滤条件
cloudregionIdArray := jsonutils.NewArray()
for _, id := range cloudregionIds {
cloudregionIdArray.Add(jsonutils.NewString(id))
}
params.Set("cloudregion_id", cloudregionIdArray)
}
if len(zoneIds) > 0 {
// 设置可用区 ID 过滤条件
zoneIdArray := jsonutils.NewArray()
for _, id := range zoneIds {
zoneIdArray.Add(jsonutils.NewString(id))
}
params.Set("zone_ids", zoneIdArray)
}
if len(providers) > 0 {
// 设置提供商过滤条件
providerArray := jsonutils.NewArray()
for _, provider := range providers {
providerArray.Add(jsonutils.NewString(provider))
}
params.Set("providers", providerArray)
}
if len(storageTypes) > 0 {
// 设置存储类型过滤条件
for _, storageType := range storageTypes {
params.Set("storage_type", jsonutils.NewString(storageType))
break
}
}
if hostId != "" {
// 设置主机 ID 过滤条件
params.Set("host_id", jsonutils.NewString(hostId))
}
// 调用 Cloudpods API 查询存储列表
result, err := compute.Storages.List(session, params)
if err != nil {
return nil, fmt.Errorf("failed to list storages: %w", err)
}
// 构造响应数据
response := &models.StorageListResponse{
Limit: int64(limit),
Offset: int64(offset),
Storages: make([]models.StorageDetails, 0),
Total: int64(result.Total),
}
// 遍历查询结果,将数据转换为响应格式
for _, data := range result.Data {
storage := models.StorageDetails{}
if err := data.Unmarshal(&storage); err != nil {
// 如果数据转换失败,记录警告日志并跳过该条数据
log.Warningf("Failed to unmarshal storage details: %s", err)
continue
}
response.Storages = append(response.Storages, storage)
}
return response, nil
}
// ListServers 查询 Cloudpods 中的服务器列表
func (a *CloudpodsAdapter) ListServers(ctx context.Context, limit int, offset int, search string, status string, ak string, sk string) (*models.ServerListResponse, error) {
// 获取 Cloudpods 会话
session, err := a.getSession(ctx, ak, sk)
if err != nil {
return nil, err
}
// 构造查询参数
params := jsonutils.NewDict()
params.Set("scope", jsonutils.NewString("max"))
if limit > 0 {
// 设置查询结果数量限制
params.Set("limit", jsonutils.NewInt(int64(limit)))
}
if offset > 0 {
// 设置查询偏移量
params.Set("offset", jsonutils.NewInt(int64(offset)))
}
if search != "" {
// 设置搜索关键字
params.Set("search", jsonutils.NewString(search))
}
if status != "" {
// 设置服务器状态过滤条件
params.Set("status", jsonutils.NewString(status))
}
// 调用 Cloudpods API 查询服务器列表
result, err := compute.Servers.List(session, params)
if err != nil {
return nil, fmt.Errorf("failed to list servers: %w", err)
}
// 构造响应数据
response := &models.ServerListResponse{
Limit: int64(limit),
Offset: int64(offset),
Servers: make([]models.ServerDetails, 0),
Total: int64(result.Total),
}
// 遍历查询结果,将数据转换为响应格式
for _, data := range result.Data {
server := models.ServerDetails{}
if err := data.Unmarshal(&server); err != nil {
// 如果数据转换失败,记录警告日志并跳过该条数据
log.Warningf("Failed to unmarshal server details: %s", err)
continue
}
response.Servers = append(response.Servers, server)
}
return response, nil
}