From 03701f9566caa052f81d270f4655e61c1b3eb73e Mon Sep 17 00:00:00 2001 From: Nathan Coad Date: Fri, 13 Sep 2024 10:08:36 +1000 Subject: [PATCH] search for vm with datacenter info in cloud event --- internal/vcenter/vcenter.go | 47 +++++++++++++++++++++++++++++++++++++ server/handler/vmCreate.go | 12 ++++++++-- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/internal/vcenter/vcenter.go b/internal/vcenter/vcenter.go index 49cdd72..1568ae8 100644 --- a/internal/vcenter/vcenter.go +++ b/internal/vcenter/vcenter.go @@ -10,6 +10,7 @@ import ( "github.com/vmware/govmomi" "github.com/vmware/govmomi/find" + "github.com/vmware/govmomi/object" "github.com/vmware/govmomi/view" "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/soap" @@ -158,3 +159,49 @@ func (v *Vcenter) FindVMByID(vmID string) (*VmProperties, error) { return nil, fmt.Errorf("VM with ID %s not found in any datacenter", vmID) } + +func (v *Vcenter) FindVMByIDWithDatacenter(vmID string, dcID string) (*VmProperties, error) { + + v.Logger.Debug("searching for vm id", "vm_id", vmID, "datacenter_id", dcID) + + finder := find.NewFinder(v.client.Client, true) + + // Create a ManagedObjectReference for the datacenter + dcRef := types.ManagedObjectReference{ + Type: "Datacenter", + Value: dcID, + } + + // Convert the reference to a Datacenter object + datacenter := object.NewDatacenter(v.client.Client, dcRef) + if datacenter == nil { + return nil, fmt.Errorf("Datacenter with id %s not found", dcID) + } + + // Use finder.SetDatacenter to set the datacenter + finder.SetDatacenter(datacenter) + + // Create a ManagedObjectReference for the VM + vmRef := types.ManagedObjectReference{ + Type: "VirtualMachine", + Value: vmID, + } + + var vm mo.VirtualMachine + err := v.client.RetrieveOne(v.ctx, vmRef, []string{"config", "name"}, &vm) + + if err == nil { + return &VmProperties{ + Datacenter: datacenter.Name(), + Vm: vm, + }, nil + } else if _, ok := err.(*find.NotFoundError); !ok { + // If the error is not a NotFoundError, return it + //return nil, fmt.Errorf("failed to retrieve VM with ID %s in datacenter %s: %w", vmID, dc.Name(), err) + v.Logger.Debug("Couldn't find vm in datacenter", "vm_id", vmID, "datacenter_name", datacenter.Name()) + } else if err != nil { + return nil, fmt.Errorf("failed to retrieve VM: %w", err) + } + + return nil, fmt.Errorf("VM with ID %s not found in any datacenter", vmID) +} diff --git a/server/handler/vmCreate.go b/server/handler/vmCreate.go index 9dfe91b..555f566 100644 --- a/server/handler/vmCreate.go +++ b/server/handler/vmCreate.go @@ -21,6 +21,7 @@ func (h *Handler) VmCreate(w http.ResponseWriter, r *http.Request) { unixTimestamp int64 numVcpus int32 numRam int32 + datacenter string ) reqBody, err := io.ReadAll(r.Body) @@ -63,9 +64,16 @@ func (h *Handler) VmCreate(w http.ResponseWriter, r *http.Request) { vc := vcenter.New(h.Logger) vc.Login(vm.CloudEvent.Source) //vmObject, err := vc.FindVMByName(vm.CloudEvent.Data.VM.Name) - vmObject, err := vc.FindVMByID(vm.CloudEvent.Data.VM.VM.Value) + //vmObject, err := vc.FindVMByID(vm.CloudEvent.Data.VM.VM.Value) + vmObject, err := vc.FindVMByIDWithDatacenter(vm.CloudEvent.Data.VM.VM.Value, vm.CloudEvent.Data.Datacenter.Datacenter.Value) + if err != nil { h.Logger.Error("Can't locate vm in vCenter", "vmID", vm.CloudEvent.Data.VM.VM.Value, "error", err) + } else if vmObject == nil { + h.Logger.Debug("didn't find VM", "vm_id", vm.CloudEvent.Data.VM.VM.Value) + numRam = 0 + numVcpus = 0 + datacenter = "" } else { h.Logger.Debug("found VM", "object", vmObject) //prettyPrint(vmObject) @@ -86,7 +94,7 @@ func (h *Handler) VmCreate(w http.ResponseWriter, r *http.Request) { EventId: sql.NullString{String: vm.CloudEvent.ID, Valid: vm.CloudEvent.ID != ""}, EventKey: sql.NullString{String: strconv.Itoa(vm.CloudEvent.Data.Key), Valid: strconv.Itoa(vm.CloudEvent.Data.Key) != ""}, VmId: sql.NullString{String: vm.CloudEvent.Data.VM.VM.Value, Valid: vm.CloudEvent.Data.VM.VM.Value != ""}, - Datacenter: sql.NullString{String: vmObject.Datacenter, Valid: vmObject.Datacenter != ""}, + Datacenter: sql.NullString{String: datacenter, Valid: datacenter != ""}, CreationTime: sql.NullInt64{Int64: unixTimestamp, Valid: unixTimestamp > 0}, InitialVcpus: sql.NullInt64{Int64: int64(numVcpus), Valid: numVcpus > 0}, InitialRam: sql.NullInt64{Int64: int64(numRam), Valid: numRam > 0},