63 lines
2.3 KiB
Go
63 lines
2.3 KiB
Go
package tools
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/url"
|
|
|
|
"github.com/modelcontextprotocol/go-sdk/mcp"
|
|
)
|
|
|
|
// vm_cloudinit.go — настройка cloud-init гостя (только QEMU): ciuser,
|
|
// cipassword, ipconfig0/1.., sshkeys. Структурная мутация → confirm + gate.
|
|
// Для гостей-ВМ; LXC-cloud-init не поддерживается PVE API.
|
|
|
|
func registerVMCloudInitTools(s *mcp.Server) {
|
|
registerPatternTool(s, &mcp.Tool{
|
|
Name: "vm_set_cloudinit",
|
|
Description: "Set cloud-init options of a QEMU VM: user, password, per-NIC ipconfig, SSH keys. Requires confirm + write permission.",
|
|
InputSchema: schema(map[string]any{
|
|
"node": strProps("Node name", true),
|
|
"vmid": strProps("VM ID", true),
|
|
"ciuser": strProps("Cloud-init login user", false),
|
|
"cipassword": strProps("Cloud-init login password", false),
|
|
"sshkeys": strProps("Public SSH key(s) for the user", false),
|
|
"ipconfig0": strProps("ipconfig0 spec, e.g. ip=dhcp or ip=192.168.1.10/24,gw=192.168.102.100", false),
|
|
"confirm": strProps("Set to \"true\" to confirm", true, "true"),
|
|
}, []string{"node", "vmid", "confirm"}),
|
|
}, vmPatterns, vmSetCloudInitHandler)
|
|
}
|
|
|
|
func vmSetCloudInitHandler(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
t, err := tenantFor(ctx, req)
|
|
if err != nil {
|
|
return errorResult(err.Error()), nil
|
|
}
|
|
args := requestArgs(req)
|
|
node, vmid, host, r := resolveVMArgs(t, args)
|
|
if r != nil {
|
|
return r, nil
|
|
}
|
|
if err := confirm(args, "vm_set_cloudinit"); err != nil {
|
|
return errorResult(err.Error()), nil
|
|
}
|
|
if err := gateVMWrite(t, host, vmid); err != nil {
|
|
return errorResult(err.Error()), nil
|
|
}
|
|
form := url.Values{}
|
|
for _, k := range []string{"ciuser", "cipassword", "sshkeys", "ipconfig0"} {
|
|
if v := getString(args, k, ""); v != "" {
|
|
form.Set(k, v)
|
|
}
|
|
}
|
|
if len(form) == 0 {
|
|
return errorResult("at least one cloud-init field is required"), nil
|
|
}
|
|
// Включаем cloud-init диск (для OVMF/машин с cidata) — обычно ide2:cloudinit.
|
|
upid, err := t.ConfigPost(ctx, host, node, vmTypeQEMU, vmid, form)
|
|
if err != nil {
|
|
return errorResult(err.Error()), nil
|
|
}
|
|
return textResult(upidMsg("vm_set_cloudinit", fmt.Sprintf("%s/%d", node, vmid), upid)), nil
|
|
}
|