package handler import ( "database/sql" "errors" "fmt" "net/http" "strconv" "time" "vctp/db/queries" models "vctp/server/models" ) // VmMoveEvent records a VM move CloudEvent as an update. // @Summary Record VM move event (deprecated) // @Description Deprecated: Parses a VM move CloudEvent and creates an update record. // @Tags events // @Deprecated // @Accept json // @Produce json // @Param event body models.CloudEventReceived true "CloudEvent payload" // @Success 200 {object} models.StatusMessageResponse "Move event processed" // @Failure 400 {object} models.ErrorResponse "Invalid request" // @Failure 500 {object} models.ErrorResponse "Server error" // @Router /api/event/vm/move [post] func (h *Handler) VmMoveEvent(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { writeJSONError(w, http.StatusMethodNotAllowed, "method not allowed") return } if h.denyLegacyAPI(w, "/api/event/vm/move") { return } params := queries.CreateUpdateParams{} var unixTimestamp int64 ctx, cancel := withRequestTimeout(r, defaultRequestTimeout) defer cancel() var event models.CloudEventReceived if err := decodeJSONBody(w, r, &event); err != nil { h.Logger.Error("unable to unmarshal json", "error", err) writeJSONError(w, http.StatusBadRequest, fmt.Sprintf("Unable to unmarshal JSON in request body: '%s'", err)) return } else { h.Logger.Debug("successfully decoded JSON") //prettyPrint(event) } if event.CloudEvent.Data.OldParent == nil || event.CloudEvent.Data.NewParent == nil { h.Logger.Error("No resource pool data found in cloud event") prettyPrint(event) writeJSONError(w, http.StatusBadRequest, "CloudEvent missing resource pool data") return } h.Logger.Debug("Checking inventory table for VM record") invParams := queries.GetInventoryVmIdParams{ VmId: sql.NullString{String: event.CloudEvent.Data.VM.VM.Value, Valid: event.CloudEvent.Data.VM.VM.Value != ""}, DatacenterName: sql.NullString{String: event.CloudEvent.Data.Datacenter.Name, Valid: event.CloudEvent.Data.Datacenter.Name != ""}, } invResult, err := h.Database.Queries().GetInventoryVmId(ctx, invParams) if err != nil { // If a VM is being moved it must exist, so lets add an inventory record for this VM h.Logger.Error("unable to find existing inventory record for this VM", "error", err) if errors.Is(err, sql.ErrNoRows) { // Add a record to the inventory table for this VM h.Logger.Info("Received VM modify event for a VM not currently in the inventory. Adding to inventory") iid, err2 := h.AddVmToInventory(event, ctx, unixTimestamp) if err2 != nil { h.Logger.Error("Received error adding VM to inventory", "error", err2) writeJSONError(w, http.StatusInternalServerError, fmt.Sprintf("Valid request but experienced error adding vm id '%s' in datacenter name '%s' to inventory table : %s", event.CloudEvent.Data.VM.VM.Value, event.CloudEvent.Data.Datacenter.Name, err2)) return } if iid > 0 { params.InventoryId = sql.NullInt64{Int64: iid, Valid: iid > 0} } else { h.Logger.Error("Received zero for inventory id when adding VM to inventory") writeJSONError(w, http.StatusInternalServerError, fmt.Sprintf("Valid request but received zero result when adding vm id '%s' in datacenter name '%s' to inventory table", event.CloudEvent.Data.VM.VM.Value, event.CloudEvent.Data.Datacenter.Name)) return } } } else { params.InventoryId = sql.NullInt64{Int64: invResult.Iid, Valid: invResult.Iid > 0} } // Parse the datetime string to a time.Time object eventTime, err := time.Parse(time.RFC3339, event.CloudEvent.Data.CreatedTime) if err != nil { h.Logger.Warn("unable to convert cloud event time to timestamp", "error", err) unixTimestamp = time.Now().Unix() } else { // Convert to Unix timestamp unixTimestamp = eventTime.Unix() } // populate other parameters for the Update database record params.NewResourcePool = sql.NullString{String: event.CloudEvent.Data.NewParent.Name, Valid: event.CloudEvent.Data.NewParent.Name != ""} params.UpdateType = "move" params.EventId = sql.NullString{String: event.CloudEvent.ID, Valid: event.CloudEvent.ID != ""} params.EventKey = sql.NullString{String: strconv.Itoa(event.CloudEvent.Data.Key), Valid: event.CloudEvent.Data.Key > 0} params.UpdateTime = sql.NullInt64{Int64: unixTimestamp, Valid: unixTimestamp > 0} params.UserName = sql.NullString{String: event.CloudEvent.Data.UserName, Valid: event.CloudEvent.Data.UserName != ""} // Create the Update database record result, err := h.Database.Queries().CreateUpdate(ctx, params) if err != nil { h.Logger.Error("unable to perform database insert", "error", err) writeJSONError(w, http.StatusInternalServerError, fmt.Sprintf("Unable to insert move event into database: '%s'", err)) return } else { h.Logger.Debug("created database record", "insert_result", result) writeJSONOKMessage(w, "Successfully processed move event") return } }