work on optimising vcenter queries
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -37,6 +37,13 @@ type VmProperties struct {
|
||||
ResourcePool string
|
||||
}
|
||||
|
||||
type HostLookup struct {
|
||||
Cluster string
|
||||
Datacenter string
|
||||
}
|
||||
|
||||
type FolderLookup map[string]string
|
||||
|
||||
// New creates a new Vcenter with the given logger
|
||||
func New(logger *slog.Logger, creds *VcenterLogin) *Vcenter {
|
||||
|
||||
@@ -143,6 +150,118 @@ func (v *Vcenter) GetAllVmReferences() ([]*object.VirtualMachine, error) {
|
||||
return results, err
|
||||
}
|
||||
|
||||
func (v *Vcenter) BuildHostLookup() (map[string]HostLookup, error) {
|
||||
finder := find.NewFinder(v.client.Client, true)
|
||||
datacenters, err := finder.DatacenterList(v.ctx, "*")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list datacenters: %w", err)
|
||||
}
|
||||
|
||||
lookup := make(map[string]HostLookup)
|
||||
clusterCache := make(map[string]string)
|
||||
|
||||
for _, dc := range datacenters {
|
||||
finder.SetDatacenter(dc)
|
||||
hosts, err := finder.HostSystemList(v.ctx, "*")
|
||||
if err != nil {
|
||||
v.Logger.Warn("failed to list hosts for datacenter", "datacenter", dc.Name(), "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
ref := host.Reference()
|
||||
var moHost mo.HostSystem
|
||||
if err := v.client.RetrieveOne(v.ctx, ref, []string{"parent"}, &moHost); err != nil {
|
||||
v.Logger.Warn("failed to retrieve host info", "host", host.Name(), "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
clusterName := ""
|
||||
if moHost.Parent != nil {
|
||||
if cached, ok := clusterCache[moHost.Parent.Value]; ok {
|
||||
clusterName = cached
|
||||
} else {
|
||||
var moCompute mo.ComputeResource
|
||||
if err := v.client.RetrieveOne(v.ctx, *moHost.Parent, []string{"name"}, &moCompute); err == nil {
|
||||
clusterName = moCompute.Name
|
||||
clusterCache[moHost.Parent.Value] = clusterName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lookup[ref.Value] = HostLookup{
|
||||
Cluster: clusterName,
|
||||
Datacenter: dc.Name(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lookup, nil
|
||||
}
|
||||
|
||||
func (v *Vcenter) BuildFolderPathLookup() (FolderLookup, error) {
|
||||
m := view.NewManager(v.client.Client)
|
||||
folders, err := m.CreateContainerView(v.ctx, v.client.ServiceContent.RootFolder, []string{"Folder"}, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer folders.Destroy(v.ctx)
|
||||
|
||||
var results []mo.Folder
|
||||
if err := folders.Retrieve(v.ctx, []string{"Folder"}, []string{"name", "parent"}, &results); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nameByID := make(map[string]string, len(results))
|
||||
parentByID := make(map[string]*types.ManagedObjectReference, len(results))
|
||||
for _, folder := range results {
|
||||
nameByID[folder.Reference().Value] = folder.Name
|
||||
parentByID[folder.Reference().Value] = folder.Parent
|
||||
}
|
||||
|
||||
paths := make(FolderLookup, len(results))
|
||||
var buildPath func(id string) string
|
||||
buildPath = func(id string) string {
|
||||
if pathValue, ok := paths[id]; ok {
|
||||
return pathValue
|
||||
}
|
||||
name, ok := nameByID[id]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
parent := parentByID[id]
|
||||
if parent == nil || parent.Type == "Datacenter" {
|
||||
paths[id] = path.Join("/", name)
|
||||
return paths[id]
|
||||
}
|
||||
if parent.Type != "Folder" {
|
||||
paths[id] = path.Join("/", name)
|
||||
return paths[id]
|
||||
}
|
||||
parentPath := buildPath(parent.Value)
|
||||
if parentPath == "" {
|
||||
paths[id] = path.Join("/", name)
|
||||
return paths[id]
|
||||
}
|
||||
paths[id] = path.Join(parentPath, name)
|
||||
return paths[id]
|
||||
}
|
||||
|
||||
for id := range nameByID {
|
||||
_ = buildPath(id)
|
||||
}
|
||||
|
||||
return paths, nil
|
||||
}
|
||||
|
||||
func (v *Vcenter) GetVMFolderPathFromLookup(vm mo.VirtualMachine, lookup FolderLookup) (string, bool) {
|
||||
if vm.Parent == nil || lookup == nil {
|
||||
return "", false
|
||||
}
|
||||
pathValue, ok := lookup[vm.Parent.Value]
|
||||
return pathValue, ok
|
||||
}
|
||||
|
||||
func (v *Vcenter) ConvertObjToMoVM(vmObj *object.VirtualMachine) (*mo.VirtualMachine, error) {
|
||||
// Use the InventoryPath to extract the datacenter name and VM path
|
||||
inventoryPath := vmObj.InventoryPath
|
||||
|
||||
Reference in New Issue
Block a user