Phase 2 of the proxmox provider plan. Adds the proxmox: config block with its validation, registers the type in the config allow-list and the constructor map, and starts internal/provider/proxmox: the api seam and its data types, providerIDs (vms/<vmid>/<name>) with the UID-derived VMID, the description mark, state mapping, and error classification. Tests read the responses captured from pv1-1 in Phase 0 rather than repeating Proxmox's wording, and every matcher is run against every captured error so none fires on the wrong message. The contract methods are Transient stubs until Phases 5 to 7. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
120 lines
4.2 KiB
Go
120 lines
4.2 KiB
Go
package proxmox
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
)
|
|
|
|
// api is the seam over the Proxmox VE REST API: one method per endpoint the
|
|
// provider uses, ctx first (spec entry 17). Calls that start a Proxmox task
|
|
// return its UPID; the caller waits on it with TaskStatus.
|
|
type api interface {
|
|
Version(ctx context.Context) (versionInfo, error)
|
|
NodeStatus(ctx context.Context, node string) (nodeStatus, error)
|
|
StorageStatus(ctx context.Context, node, storage string) (storageStatus, error)
|
|
ClusterResources(ctx context.Context) ([]vmResource, error)
|
|
VMConfig(ctx context.Context, node string, vmid int) (vmConfig, error)
|
|
SetVMConfig(ctx context.Context, node string, vmid int, params map[string]string) error
|
|
Clone(ctx context.Context, node string, vmid int, p cloneParams) (upid string, err error)
|
|
Resize(ctx context.Context, node string, vmid int, disk, size string) (upid string, err error)
|
|
Start(ctx context.Context, node string, vmid int) (upid string, err error)
|
|
Stop(ctx context.Context, node string, vmid int) (upid string, err error)
|
|
VMStatus(ctx context.Context, node string, vmid int) (vmStatus, error)
|
|
Destroy(ctx context.Context, node string, vmid int) (upid string, err error)
|
|
TaskStatus(ctx context.Context, node, upid string) (taskStatus, error)
|
|
AgentNetworkInterfaces(ctx context.Context, node string, vmid int) ([]agentInterface, error)
|
|
UploadISO(ctx context.Context, node, storage, filename string, r io.Reader, size int64) (upid string, err error)
|
|
DeleteVolume(ctx context.Context, node, storage, volid string) (upid string, err error)
|
|
}
|
|
|
|
// versionInfo is GET /version.
|
|
type versionInfo struct {
|
|
Version string `json:"version"`
|
|
Release string `json:"release"`
|
|
RepoID string `json:"repoid"`
|
|
}
|
|
|
|
// nodeStatus is the part of GET /nodes/{node}/status the Checker reports.
|
|
type nodeStatus struct {
|
|
PVEVersion string `json:"pveversion"`
|
|
CurrentKernel struct {
|
|
Release string `json:"release"`
|
|
} `json:"current-kernel"`
|
|
}
|
|
|
|
// storageStatus is GET /nodes/{node}/storage/{storage}/status. Content is a
|
|
// comma-separated list such as "iso,import,backup,vztmpl".
|
|
type storageStatus struct {
|
|
Type string `json:"type"`
|
|
Content string `json:"content"`
|
|
Active int `json:"active"`
|
|
Enabled int `json:"enabled"`
|
|
Shared int `json:"shared"`
|
|
Total int64 `json:"total"`
|
|
Used int64 `json:"used"`
|
|
Avail int64 `json:"avail"`
|
|
}
|
|
|
|
// vmResource is one entry of GET /cluster/resources?type=vm. A VM being
|
|
// cloned is listed without a name, with lock "clone" and status "unknown"
|
|
// (spec entry 9). Tags are separated by ";".
|
|
type vmResource struct {
|
|
VMID int `json:"vmid"`
|
|
Name string `json:"name"`
|
|
Node string `json:"node"`
|
|
Type string `json:"type"`
|
|
Status string `json:"status"`
|
|
Lock string `json:"lock"`
|
|
Tags string `json:"tags"`
|
|
Template int `json:"template"`
|
|
}
|
|
|
|
// vmConfig is GET /nodes/{node}/qemu/{vmid}/config with every value
|
|
// rendered as a string: Proxmox sends some scalars as JSON numbers (cores,
|
|
// template) and others as strings (memory).
|
|
type vmConfig map[string]string
|
|
|
|
// vmStatus is GET /nodes/{node}/qemu/{vmid}/status/current. QMPStatus tells
|
|
// a paused VM from a running one; the resources listing cannot.
|
|
type vmStatus struct {
|
|
Status string `json:"status"`
|
|
QMPStatus string `json:"qmpstatus"`
|
|
Name string `json:"name"`
|
|
Lock string `json:"lock"`
|
|
Uptime int64 `json:"uptime"`
|
|
}
|
|
|
|
// taskStatus is GET /nodes/{node}/tasks/{upid}/status. ExitStatus is "OK"
|
|
// or the failure's text once Status is "stopped".
|
|
type taskStatus struct {
|
|
UPID string `json:"upid"`
|
|
Type string `json:"type"`
|
|
ID string `json:"id"`
|
|
Node string `json:"node"`
|
|
Status string `json:"status"`
|
|
ExitStatus string `json:"exitstatus"`
|
|
}
|
|
|
|
// agentInterface is one entry of the guest agent's network-get-interfaces
|
|
// result.
|
|
type agentInterface struct {
|
|
Name string `json:"name"`
|
|
IPAddresses []agentIP `json:"ip-addresses"`
|
|
}
|
|
|
|
type agentIP struct {
|
|
Address string `json:"ip-address"`
|
|
Type string `json:"ip-address-type"`
|
|
Prefix int `json:"prefix"`
|
|
}
|
|
|
|
// cloneParams are the parameters of POST .../clone the provider sets.
|
|
// Storage and Target are omitted when empty.
|
|
type cloneParams struct {
|
|
NewID int
|
|
Name string
|
|
Description string
|
|
Storage string
|
|
Target string
|
|
}
|