mirror of
https://github.com/yusing/godoxy.git
synced 2026-01-11 14:20:32 +01:00
Proxmox
The proxmox package provides Proxmox VE integration for GoDoxy, enabling management of Proxmox LXC containers.
Overview
The proxmox package implements Proxmox API client management, node discovery, and LXC container operations including power management and IP address retrieval.
Key Features
- Proxmox API client management
- Node discovery and pool management
- LXC container operations (start, stop, status)
- IP address retrieval for containers
- TLS configuration options
- Token-based authentication
Architecture
graph TD
A[Proxmox Config] --> B[Create Client]
B --> C[Connect to API]
C --> D[Fetch Cluster Info]
D --> E[Discover Nodes]
E --> F[Add to Node Pool]
G[LXC Operations] --> H[Get IPs]
G --> I[Start Container]
G --> J[Stop Container]
G --> K[Check Status]
subgraph Node Pool
F --> L[Nodes Map]
L --> M[Node 1]
L --> N[Node 2]
L --> O[Node 3]
end
Core Components
Config
type Config struct {
URL string `json:"url" validate:"required,url"`
TokenID string `json:"token_id" validate:"required"`
Secret strutils.Redacted `json:"secret" validate:"required"`
NoTLSVerify bool `json:"no_tls_verify"`
client *Client
}
Client
type Client struct {
*proxmox.Client
proxmox.Cluster
Version *proxmox.Version
}
Node
type Node struct {
name string
id string
client *proxmox.Client
}
var Nodes = pool.New[*Node]("proxmox_nodes")
Public API
Configuration
// Init initializes the Proxmox client.
func (c *Config) Init(ctx context.Context) gperr.Error
// Client returns the Proxmox client.
func (c *Config) Client() *Client
Node Operations
// AvailableNodeNames returns all available node names.
func AvailableNodeNames() string
Usage
Basic Setup
proxmoxCfg := &proxmox.Config{
URL: "https://proxmox.example.com:8006",
TokenID: "user@pam!token-name",
Secret: "your-api-token-secret",
NoTLSVerify: false,
}
ctx := context.Background()
err := proxmoxCfg.Init(ctx)
if err != nil {
log.Fatal(err)
}
client := proxmoxCfg.Client()
Node Access
// Get a specific node
node, ok := proxmox.Nodes.Get("pve")
if !ok {
log.Fatal("Node not found")
}
fmt.Printf("Node: %s (%s)\n", node.Name(), node.Key())
Available Nodes
names := proxmox.AvailableNodeNames()
fmt.Printf("Available nodes: %s\n", names)
LXC Operations
Get Container IPs
func getContainerIPs(ctx context.Context, node *proxmox.Node, vmid int) ([]net.IP, error) {
var ips []net.IP
err := node.Get(ctx, "/lxc/"+strconv.Itoa(vmid)+"/config", &config)
if err != nil {
return nil, err
}
// Parse IP addresses from config
for _, ip := range config {
if ipNet := net.ParseCIDR(ip); ipNet != nil {
ips = append(ips, ipNet.IP)
}
}
return ips, nil
}
Check Container Status
func (node *Node) LXCIsRunning(ctx context.Context, vmid int) (bool, error) {
var status struct {
Status string `json:"status"`
}
err := node.Get(ctx, "/lxc/"+strconv.Itoa(vmid)+"/status/current", &status)
if err != nil {
return false, err
}
return status.Status == "running", nil
}
Start Container
func (node *Node) LXCAction(ctx context.Context, vmid int, action string) error {
return node.Post(ctx,
"/lxc/"+strconv.Itoa(vmid)+"/status/"+action,
nil,
nil,
)
}
const LXCStart = "start"
Data Flow
sequenceDiagram
participant Config
participant Client
participant NodePool
participant LXC
Config->>Client: NewClient(url, options)
Client->>ProxmoxAPI: GET /cluster/status
ProxmoxAPI-->>Client: Cluster Info
Client->>NodePool: Add Nodes
NodePool->>NodePool: Store in Pool
participant User
User->>NodePool: Get Node
NodePool-->>User: Node
User->>Node: LXCGetIPs(vmid)
Node->>ProxmoxAPI: GET /lxc/{vmid}/config
ProxmoxAPI-->>Node: Config with IPs
Node-->>User: IP addresses
User->>Node: LXCAction(vmid, "start")
Node->>ProxmoxAPI: POST /lxc/{vmid}/status/start
ProxmoxAPI-->>Node: Success
Node-->>User: Done
Configuration
YAML Configuration
providers:
proxmox:
- url: https://proxmox.example.com:8006
token_id: user@pam!token-name
secret: your-api-token-secret
no_tls_verify: false
TLS Configuration
// With TLS verification (default)
tr := gphttp.NewTransport()
// Without TLS verification (insecure)
tr := gphttp.NewTransportWithTLSConfig(&tls.Config{
InsecureSkipVerify: true,
})
Node Pool
The package maintains a global node pool:
var Nodes = pool.New[*Node]("proxmox_nodes")
Pool Operations
// Add a node
Nodes.Add(&Node{name: "pve1", id: "node/pve1", client: client})
// Get a node
node, ok := Nodes.Get("pve1")
// Iterate nodes
for _, node := range Nodes.Iter {
fmt.Printf("Node: %s\n", node.Name())
}
Integration with Route
The proxmox package integrates with the route package for idlewatcher:
// In route validation
if r.Idlewatcher != nil && r.Idlewatcher.Proxmox != nil {
node := r.Idlewatcher.Proxmox.Node
vmid := r.Idlewatcher.Proxmox.VMID
node, ok := proxmox.Nodes.Get(node)
if !ok {
return gperr.Errorf("proxmox node %s not found", node)
}
// Get container IPs
ips, err := node.LXCGetIPs(ctx, vmid)
// ... check reachability
}
Authentication
The package uses API tokens for authentication:
opts := []proxmox.Option{
proxmox.WithAPIToken(c.TokenID, c.Secret.String()),
proxmox.WithHTTPClient(&http.Client{
Transport: tr,
}),
}
Error Handling
// Timeout handling
if errors.Is(err, context.DeadlineExceeded) {
return gperr.New("timeout fetching proxmox cluster info")
}
// Connection errors
return gperr.New("failed to fetch proxmox cluster info").With(err)
Performance Considerations
- Cluster info fetched once on init
- Nodes cached in pool
- Per-operation API calls
- 3-second timeout for initial connection