[CI SKIP] bugfixes for vm deletion tracking
This commit is contained in:
@@ -7,8 +7,10 @@ import (
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/vmware/govmomi"
|
||||
"github.com/vmware/govmomi/event"
|
||||
"github.com/vmware/govmomi/find"
|
||||
"github.com/vmware/govmomi/object"
|
||||
"github.com/vmware/govmomi/view"
|
||||
@@ -195,6 +197,90 @@ func (v *Vcenter) GetAllVMsWithProps() ([]mo.VirtualMachine, error) {
|
||||
return vms, nil
|
||||
}
|
||||
|
||||
// FindVmDeletionEvents returns a map of MoRef (VmId) to the deletion event time within the given window.
|
||||
func (v *Vcenter) FindVmDeletionEvents(ctx context.Context, begin, end time.Time) (map[string]time.Time, error) {
|
||||
result := make(map[string]time.Time)
|
||||
if v.client == nil || !v.client.Valid() {
|
||||
return result, fmt.Errorf("vcenter client is not valid")
|
||||
}
|
||||
// vCenter events are stored in UTC; normalize the query window.
|
||||
beginUTC := begin.UTC()
|
||||
endUTC := end.UTC()
|
||||
mgr := event.NewManager(v.client.Client)
|
||||
|
||||
processEvents := func(evts []types.BaseEvent) {
|
||||
for _, ev := range evts {
|
||||
switch e := ev.(type) {
|
||||
case *types.VmRemovedEvent:
|
||||
if e.Vm != nil {
|
||||
vmID := e.Vm.Vm.Value
|
||||
if vmID != "" {
|
||||
result[vmID] = e.CreatedTime
|
||||
}
|
||||
}
|
||||
case *types.TaskEvent:
|
||||
// Fallback for destroy task events.
|
||||
if e.Info.Entity != nil {
|
||||
vmID := e.Info.Entity.Value
|
||||
msg := strings.ToLower(e.GetEvent().FullFormattedMessage)
|
||||
if vmID != "" && (strings.Contains(msg, "destroy") || strings.Contains(msg, "deleted")) {
|
||||
result[vmID] = e.CreatedTime
|
||||
}
|
||||
}
|
||||
case *types.VmEvent:
|
||||
if e.Vm != nil {
|
||||
vmID := e.Vm.Vm.Value
|
||||
if vmID != "" {
|
||||
result[vmID] = e.CreatedTime
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// First attempt: specific deletion event types.
|
||||
filter := types.EventFilterSpec{
|
||||
Time: &types.EventFilterSpecByTime{
|
||||
BeginTime: &beginUTC,
|
||||
EndTime: &endUTC,
|
||||
},
|
||||
EventTypeId: []string{
|
||||
"VmRemovedEvent",
|
||||
"TaskEvent",
|
||||
},
|
||||
}
|
||||
collector, err := mgr.CreateCollectorForEvents(ctx, filter)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to create event collector: %w", err)
|
||||
}
|
||||
defer collector.Destroy(ctx)
|
||||
|
||||
events, err := collector.ReadNextEvents(ctx, 500)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to read events: %w", err)
|
||||
}
|
||||
processEvents(events)
|
||||
|
||||
// If nothing found, widen the filter to all event types in the window as a fallback.
|
||||
if len(result) == 0 {
|
||||
fallbackFilter := types.EventFilterSpec{
|
||||
Time: &types.EventFilterSpecByTime{
|
||||
BeginTime: &beginUTC,
|
||||
EndTime: &endUTC,
|
||||
},
|
||||
}
|
||||
fc, err := mgr.CreateCollectorForEvents(ctx, fallbackFilter)
|
||||
if err == nil {
|
||||
defer fc.Destroy(ctx)
|
||||
if evs, readErr := fc.ReadNextEvents(ctx, 500); readErr == nil {
|
||||
processEvents(evs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (v *Vcenter) BuildHostLookup() (map[string]HostLookup, error) {
|
||||
finder := find.NewFinder(v.client.Client, true)
|
||||
datacenters, err := finder.DatacenterList(v.ctx, "*")
|
||||
@@ -415,6 +501,10 @@ func (v *Vcenter) GetHostSystemObject(hostRef types.ManagedObjectReference) (*mo
|
||||
|
||||
// Function to find the cluster or compute resource from a host reference
|
||||
func (v *Vcenter) GetClusterFromHost(hostRef *types.ManagedObjectReference) (string, error) {
|
||||
if hostRef == nil {
|
||||
v.Logger.Warn("nil hostRef passed to GetClusterFromHost")
|
||||
return "", nil
|
||||
}
|
||||
// Get the host object
|
||||
host, err := v.GetHostSystemObject(*hostRef)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user