Files
Sankofa/crossplane-provider-proxmox/pkg/discovery/proxmox.go
defiQUG 9daf1fd378 Apply Composer changes: comprehensive API updates, migrations, middleware, and infrastructure improvements
- Add comprehensive database migrations (001-024) for schema evolution
- Enhance API schema with expanded type definitions and resolvers
- Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth
- Implement new services: AI optimization, billing, blockchain, compliance, marketplace
- Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage)
- Update Crossplane provider with enhanced VM management capabilities
- Add comprehensive test suite for API endpoints and services
- Update frontend components with improved GraphQL subscriptions and real-time updates
- Enhance security configurations and headers (CSP, CORS, etc.)
- Update documentation and configuration files
- Add new CI/CD workflows and validation scripts
- Implement design system improvements and UI enhancements
2025-12-12 18:01:35 -08:00

237 lines
6.6 KiB
Go

package discovery
import (
"context"
"fmt"
"github.com/pkg/errors"
"github.com/sankofa/crossplane-provider-proxmox/pkg/proxmox"
)
// ProxmoxDiscoveryAgent discovers Proxmox resources
type ProxmoxDiscoveryAgent struct {
client *proxmox.Client
site string
region string
}
// NewProxmoxDiscoveryAgent creates a new Proxmox discovery agent
func NewProxmoxDiscoveryAgent(client *proxmox.Client, site, region string) *ProxmoxDiscoveryAgent {
return &ProxmoxDiscoveryAgent{
client: client,
site: site,
region: region,
}
}
// DiscoveredResource represents a discovered resource
type DiscoveredResource struct {
ResourceType string
Provider string
ProviderID string
ProviderResourceID string
Name string
Region string
SiteID string
Metadata map[string]interface{}
Tags []string
}
// DiscoverVMs discovers all VMs in the Proxmox cluster
func (a *ProxmoxDiscoveryAgent) DiscoverVMs(ctx context.Context) ([]DiscoveredResource, error) {
// Use Proxmox API to list all VMs
// This requires implementing ListVMs in the Proxmox client
// For now, we'll make a direct API call
// Get cluster nodes first
nodes, err := a.client.ListNodes(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to list nodes")
}
var resources []DiscoveredResource
// List VMs from each node
for _, node := range nodes {
vms, err := a.client.ListVMs(ctx, node)
if err != nil {
// Log error but continue with other nodes
continue
}
for _, vm := range vms {
resources = append(resources, DiscoveredResource{
ResourceType: "VM",
Provider: "PROXMOX",
ProviderID: fmt.Sprintf("%d", vm.ID),
ProviderResourceID: fmt.Sprintf("proxmox://nodes/%s/qemu/%d", node, vm.ID),
Name: vm.Name,
Region: a.region,
SiteID: a.site,
Metadata: map[string]interface{}{
"node": node,
"vmId": vm.ID,
"status": vm.Status,
"ip": vm.IP,
"created": vm.Created,
},
Tags: []string{fmt.Sprintf("node:%s", node)},
})
}
}
return resources, nil
}
// DiscoverStoragePools discovers all storage pools
func (a *ProxmoxDiscoveryAgent) DiscoverStoragePools(ctx context.Context) ([]DiscoveredResource, error) {
// List storage pools from Proxmox API
storages, err := a.client.ListStorages(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to list storage pools")
}
var resources []DiscoveredResource
for _, storage := range storages {
resources = append(resources, DiscoveredResource{
ResourceType: "STORAGE",
Provider: "PROXMOX",
ProviderID: storage.Name,
ProviderResourceID: fmt.Sprintf("proxmox://storage/%s", storage.Name),
Name: storage.Name,
Region: a.region,
SiteID: a.site,
Metadata: map[string]interface{}{
"type": storage.Type,
"content": storage.Content,
"shared": storage.Shared,
"enabled": storage.Enabled,
"capacity": storage.Capacity,
"used": storage.Used,
},
Tags: []string{fmt.Sprintf("type:%s", storage.Type)},
})
}
return resources, nil
}
// DiscoverNetworks discovers all network bridges
func (a *ProxmoxDiscoveryAgent) DiscoverNetworks(ctx context.Context) ([]DiscoveredResource, error) {
// Get cluster nodes first
nodes, err := a.client.ListNodes(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to list nodes")
}
var resources []DiscoveredResource
seenNetworks := make(map[string]bool)
// List networks from each node
for _, node := range nodes {
networks, err := a.client.ListNetworks(ctx, node)
if err != nil {
// Log error but continue with other nodes
continue
}
for _, network := range networks {
// Avoid duplicates (same network on multiple nodes)
networkKey := fmt.Sprintf("%s-%s", network.Name, network.Type)
if seenNetworks[networkKey] {
continue
}
seenNetworks[networkKey] = true
resources = append(resources, DiscoveredResource{
ResourceType: "NETWORK",
Provider: "PROXMOX",
ProviderID: network.Name,
ProviderResourceID: fmt.Sprintf("proxmox://nodes/%s/network/%s", node, network.Name),
Name: network.Name,
Region: a.region,
SiteID: a.site,
Metadata: map[string]interface{}{
"node": node,
"type": network.Type,
"bridge": network.Bridge,
"vlan": network.VLAN,
"active": network.Active,
"autostart": network.Autostart,
},
Tags: []string{fmt.Sprintf("type:%s", network.Type)},
})
}
}
return resources, nil
}
// DiscoverClusters discovers Proxmox clusters
func (a *ProxmoxDiscoveryAgent) DiscoverClusters(ctx context.Context) ([]DiscoveredResource, error) {
// Get cluster information
clusterInfo, err := a.client.GetClusterInfo(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to get cluster info")
}
var resources []DiscoveredResource
// Add cluster as a resource
resources = append(resources, DiscoveredResource{
ResourceType: "CLUSTER",
Provider: "PROXMOX",
ProviderID: clusterInfo.Name,
ProviderResourceID: fmt.Sprintf("proxmox://cluster/%s", clusterInfo.Name),
Name: clusterInfo.Name,
Region: a.region,
SiteID: a.site,
Metadata: map[string]interface{}{
"nodes": clusterInfo.Nodes,
"quorum": clusterInfo.Quorum,
"version": clusterInfo.Version,
"nodeCount": len(clusterInfo.Nodes),
},
Tags: []string{"cluster"},
})
return resources, nil
}
// DiscoverAll discovers all Proxmox resources
func (a *ProxmoxDiscoveryAgent) DiscoverAll(ctx context.Context) ([]DiscoveredResource, error) {
var allResources []DiscoveredResource
// Discover VMs
vms, err := a.DiscoverVMs(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to discover VMs")
}
allResources = append(allResources, vms...)
// Discover storage pools
storagePools, err := a.DiscoverStoragePools(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to discover storage pools")
}
allResources = append(allResources, storagePools...)
// Discover networks
networks, err := a.DiscoverNetworks(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to discover networks")
}
allResources = append(allResources, networks...)
// Discover clusters
clusters, err := a.DiscoverClusters(ctx)
if err != nil {
return nil, errors.Wrap(err, "failed to discover clusters")
}
allResources = append(allResources, clusters...)
return allResources, nil
}