optimise vcenter collection [CI SKIP]
This commit is contained in:
@@ -601,7 +601,7 @@ func normalizeResourcePool(value string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func snapshotFromVM(vmObject *mo.VirtualMachine, vc *vcenter.Vcenter, snapshotTime time.Time, inv *queries.Inventory, hostLookup map[string]vcenter.HostLookup, folderLookup vcenter.FolderLookup) (inventorySnapshotRow, error) {
|
func snapshotFromVM(vmObject *mo.VirtualMachine, vc *vcenter.Vcenter, snapshotTime time.Time, inv *queries.Inventory, hostLookup map[string]vcenter.HostLookup, folderLookup vcenter.FolderLookup, rpLookup map[string]string) (inventorySnapshotRow, error) {
|
||||||
if vmObject == nil {
|
if vmObject == nil {
|
||||||
return inventorySnapshotRow{}, fmt.Errorf("missing VM object")
|
return inventorySnapshotRow{}, fmt.Errorf("missing VM object")
|
||||||
}
|
}
|
||||||
@@ -690,9 +690,16 @@ func snapshotFromVM(vmObject *mo.VirtualMachine, vc *vcenter.Vcenter, snapshotTi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if row.ResourcePool.String == "" {
|
if row.ResourcePool.String == "" && vmObject.ResourcePool != nil {
|
||||||
if rpName, err := vc.GetVmResourcePool(*vmObject); err == nil {
|
if rpLookup != nil {
|
||||||
row.ResourcePool = sql.NullString{String: normalizeResourcePool(rpName), Valid: rpName != ""}
|
if rpName, ok := rpLookup[vmObject.ResourcePool.Value]; ok {
|
||||||
|
row.ResourcePool = sql.NullString{String: normalizeResourcePool(rpName), Valid: rpName != ""}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !row.ResourcePool.Valid {
|
||||||
|
if rpName, err := vc.GetVmResourcePool(*vmObject); err == nil {
|
||||||
|
row.ResourcePool = sql.NullString{String: normalizeResourcePool(rpName), Valid: rpName != ""}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,7 +812,7 @@ func (c *CronTask) captureHourlySnapshotForVcenter(ctx context.Context, startTim
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
vcVms, err := vc.GetAllVmReferences()
|
vcVms, err := vc.GetAllVMsWithProps()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get VMs from vcenter: %w", err)
|
return fmt.Errorf("unable to get VMs from vcenter: %w", err)
|
||||||
}
|
}
|
||||||
@@ -827,6 +834,13 @@ func (c *CronTask) captureHourlySnapshotForVcenter(ctx context.Context, startTim
|
|||||||
} else {
|
} else {
|
||||||
c.Logger.Debug("built folder lookup", "url", url, "folders", len(folderLookup))
|
c.Logger.Debug("built folder lookup", "url", url, "folders", len(folderLookup))
|
||||||
}
|
}
|
||||||
|
rpLookup, err := vc.BuildResourcePoolLookup()
|
||||||
|
if err != nil {
|
||||||
|
c.Logger.Warn("failed to build resource pool lookup", "url", url, "error", err)
|
||||||
|
rpLookup = nil
|
||||||
|
} else {
|
||||||
|
c.Logger.Debug("built resource pool lookup", "url", url, "pools", len(rpLookup))
|
||||||
|
}
|
||||||
|
|
||||||
inventoryRows, err := c.Database.Queries().GetInventoryByVcenter(ctx, url)
|
inventoryRows, err := c.Database.Queries().GetInventoryByVcenter(ctx, url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -844,16 +858,11 @@ func (c *CronTask) captureHourlySnapshotForVcenter(ctx context.Context, startTim
|
|||||||
presentSnapshots := make(map[string]inventorySnapshotRow, len(vcVms))
|
presentSnapshots := make(map[string]inventorySnapshotRow, len(vcVms))
|
||||||
totals := snapshotTotals{}
|
totals := snapshotTotals{}
|
||||||
for _, vm := range vcVms {
|
for _, vm := range vcVms {
|
||||||
if strings.HasPrefix(vm.Name(), "vCLS-") {
|
if strings.HasPrefix(vm.Name, "vCLS-") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
vmObj, err := vc.ConvertObjToMoVM(vm)
|
if vm.Config != nil && vm.Config.Template {
|
||||||
if err != nil {
|
|
||||||
c.Logger.Error("failed to read VM details", "vm_id", vm.Reference().Value, "error", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if vmObj.Config != nil && vmObj.Config.Template {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,7 +872,7 @@ func (c *CronTask) captureHourlySnapshotForVcenter(ctx context.Context, startTim
|
|||||||
inv = &existingCopy
|
inv = &existingCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
row, err := snapshotFromVM(vmObj, vc, startTime, inv, hostLookup, folderLookup)
|
row, err := snapshotFromVM(&vm, vc, startTime, inv, hostLookup, folderLookup, rpLookup)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Logger.Error("unable to build snapshot for VM", "vm_id", vm.Reference().Value, "error", err)
|
c.Logger.Error("unable to build snapshot for VM", "vm_id", vm.Reference().Value, "error", err)
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -150,6 +150,34 @@ func (v *Vcenter) GetAllVmReferences() ([]*object.VirtualMachine, error) {
|
|||||||
return results, err
|
return results, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAllVMsWithProps returns all VMs with the properties needed for snapshotting in a single property-collector call.
|
||||||
|
func (v *Vcenter) GetAllVMsWithProps() ([]mo.VirtualMachine, error) {
|
||||||
|
m := view.NewManager(v.client.Client)
|
||||||
|
cv, err := m.CreateContainerView(v.ctx, v.client.ServiceContent.RootFolder, []string{"VirtualMachine"}, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create VM container view: %w", err)
|
||||||
|
}
|
||||||
|
defer cv.Destroy(v.ctx)
|
||||||
|
|
||||||
|
var vms []mo.VirtualMachine
|
||||||
|
props := []string{
|
||||||
|
"name",
|
||||||
|
"parent",
|
||||||
|
"config.uuid",
|
||||||
|
"config.createDate",
|
||||||
|
"config.hardware",
|
||||||
|
"config.managedBy",
|
||||||
|
"config.template",
|
||||||
|
"runtime.powerState",
|
||||||
|
"runtime.host",
|
||||||
|
"resourcePool",
|
||||||
|
}
|
||||||
|
if err := cv.Retrieve(v.ctx, []string{"VirtualMachine"}, props, &vms); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to retrieve VMs: %w", err)
|
||||||
|
}
|
||||||
|
return vms, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (v *Vcenter) BuildHostLookup() (map[string]HostLookup, error) {
|
func (v *Vcenter) BuildHostLookup() (map[string]HostLookup, error) {
|
||||||
finder := find.NewFinder(v.client.Client, true)
|
finder := find.NewFinder(v.client.Client, true)
|
||||||
datacenters, err := finder.DatacenterList(v.ctx, "*")
|
datacenters, err := finder.DatacenterList(v.ctx, "*")
|
||||||
@@ -586,6 +614,27 @@ func (v *Vcenter) GetVmResourcePool(vm mo.VirtualMachine) (string, error) {
|
|||||||
return resourcePool, nil
|
return resourcePool, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildResourcePoolLookup creates a cache of resource pool MoRef -> name for fast lookups.
|
||||||
|
func (v *Vcenter) BuildResourcePoolLookup() (map[string]string, error) {
|
||||||
|
m := view.NewManager(v.client.Client)
|
||||||
|
cv, err := m.CreateContainerView(v.ctx, v.client.ServiceContent.RootFolder, []string{"ResourcePool"}, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create resource pool view: %w", err)
|
||||||
|
}
|
||||||
|
defer cv.Destroy(v.ctx)
|
||||||
|
|
||||||
|
var pools []mo.ResourcePool
|
||||||
|
if err := cv.Retrieve(v.ctx, []string{"ResourcePool"}, []string{"name"}, &pools); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to retrieve resource pools: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
lookup := make(map[string]string, len(pools))
|
||||||
|
for _, pool := range pools {
|
||||||
|
lookup[pool.Reference().Value] = pool.Name
|
||||||
|
}
|
||||||
|
return lookup, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to retrieve the full folder path for the VM
|
// Helper function to retrieve the full folder path for the VM
|
||||||
func (v *Vcenter) GetVMFolderPath(vm mo.VirtualMachine) (string, error) {
|
func (v *Vcenter) GetVMFolderPath(vm mo.VirtualMachine) (string, error) {
|
||||||
//finder := find.NewFinder(v.client.Client, true)
|
//finder := find.NewFinder(v.client.Client, true)
|
||||||
|
|||||||
Reference in New Issue
Block a user