Initial commit: forge-tools-proxmox — MCP-сервер для Proxmox VE
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user