From 282459ccf831d9f290ecd836daf44c92c945425f Mon Sep 17 00:00:00 2001 From: Nathan Coad Date: Mon, 16 Sep 2024 10:50:05 +1000 Subject: [PATCH] add code to handle deletion event --- db/queries/query.sql | 5 ++++ db/queries/query.sql.go | 17 +++++++++++ server/handler/vmDelete.go | 60 ++++++++++++++++++++++++++++++++++++-- server/models/models.go | 7 ++--- 4 files changed, 82 insertions(+), 7 deletions(-) diff --git a/db/queries/query.sql b/db/queries/query.sql index 6f8792c..e47356f 100644 --- a/db/queries/query.sql +++ b/db/queries/query.sql @@ -22,6 +22,11 @@ INSERT INTO "Inventory" ( ) RETURNING *; +-- name: InventoryMarkDeleted :exec +UPDATE "Inventory" +SET "DeletionTime" = sqlc.arg('deletionTime') +WHERE "VmId" = sqlc.arg('vmId') AND "Datacenter" = sqlc.arg('datacenterName'); + -- name: CreateUpdate :one INSERT INTO "Updates" ( "InventoryId", "EventKey", "EventId", "UpdateTime", "UpdateType", "NewVcpus", "NewRam", "NewResourcePool" diff --git a/db/queries/query.sql.go b/db/queries/query.sql.go index b0ff838..f939023 100644 --- a/db/queries/query.sql.go +++ b/db/queries/query.sql.go @@ -302,6 +302,23 @@ func (q *Queries) GetInventoryVmId(ctx context.Context, vmid sql.NullString) (In return i, err } +const inventoryMarkDeleted = `-- name: InventoryMarkDeleted :exec +UPDATE "Inventory" +SET "DeletionTime" = ?1 +WHERE "VmId" = ?2 AND "Datacenter" = ?3 +` + +type InventoryMarkDeletedParams struct { + DeletionTime sql.NullInt64 + VmId sql.NullString + DatacenterName sql.NullString +} + +func (q *Queries) InventoryMarkDeleted(ctx context.Context, arg InventoryMarkDeletedParams) error { + _, err := q.db.ExecContext(ctx, inventoryMarkDeleted, arg.DeletionTime, arg.VmId, arg.DatacenterName) + return err +} + const listEvents = `-- name: ListEvents :many SELECT Eid, CloudId, Source, EventTime, ChainId, VmId, EventKey, DatacenterName, ComputeResourceName, UserName, Processed, DatacenterId, ComputeResourceId, VmName, EventType FROM "Events" ORDER BY "EventTime" diff --git a/server/handler/vmDelete.go b/server/handler/vmDelete.go index 50ecaa5..e36896f 100644 --- a/server/handler/vmDelete.go +++ b/server/handler/vmDelete.go @@ -1,21 +1,75 @@ package handler import ( + "context" + "database/sql" + "encoding/json" "fmt" "io" "net/http" + "time" + "vctp/db/queries" + models "vctp/server/models" ) // VmUpdate receives the CloudEvent for a VM modification or move func (h *Handler) VmDelete(w http.ResponseWriter, r *http.Request) { + var ( + deletedTimestamp int64 + ) + reqBody, err := io.ReadAll(r.Body) if err != nil { + h.Logger.Error("Invalid data received", "error", err) fmt.Fprintf(w, "Invalid data received") w.WriteHeader(http.StatusInternalServerError) return + } else { + h.Logger.Debug("received input data", "length", len(reqBody)) } - h.Logger.Debug("received delete request", "body", string(reqBody)) - w.WriteHeader(http.StatusOK) - fmt.Fprintf(w, "Delete Request (%d): %v\n", len(reqBody), string(reqBody)) + // Decode the JSON body into CloudEventReceived struct + var event models.CloudEventReceived + if err := json.Unmarshal(reqBody, &event); err != nil { + h.Logger.Error("unable to decode json", "error", err) + http.Error(w, "Invalid JSON body", http.StatusBadRequest) + return + } else { + h.Logger.Debug("successfully decoded JSON") + prettyPrint(event) + } + + // Use the event CreatedTime to update the DeletionTime column in the VM inventory table + // 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) + deletedTimestamp = time.Now().Unix() + } else { + // Convert to Unix timestamp + deletedTimestamp = eventTime.Unix() + } + + // create the database parameters + params := queries.InventoryMarkDeletedParams{ + DeletionTime: sql.NullInt64{Int64: deletedTimestamp, Valid: deletedTimestamp > 0}, + 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 != ""}, + } + h.Logger.Debug("database params", "params", params) + err = h.Database.Queries().InventoryMarkDeleted(context.Background(), params) + + if err != nil { + h.Logger.Error("Error received marking VM as deleted", "error", err) + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Delete Request unsuccessful %s\n", err) + } else { + w.WriteHeader(http.StatusOK) + // TODO - return some JSON + fmt.Fprintf(w, "Processed VM Deletion event successfully") + } + + //h.Logger.Debug("received delete request", "body", string(reqBody)) + //w.WriteHeader(http.StatusOK) + //fmt.Fprintf(w, "Delete Request (%d): %v\n", len(reqBody), string(reqBody)) } diff --git a/server/models/models.go b/server/models/models.go index 1fae9b4..64c25b7 100644 --- a/server/models/models.go +++ b/server/models/models.go @@ -2,7 +2,6 @@ package models import ( "encoding/json" - "time" ) type CloudEventReceived struct { @@ -11,7 +10,7 @@ type CloudEventReceived struct { Specversion string `json:"specversion"` Source string `json:"source"` Type string `json:"type"` - Time string `json:"time"` + Time string `json:"time"` // Modified from time.Time Data struct { ChainID int `json:"ChainId"` ChangeTag string `json:"ChangeTag"` @@ -22,7 +21,7 @@ type CloudEventReceived struct { } `json:"ComputeResource"` Name string `json:"Name"` } `json:"ComputeResource"` - CreatedTime time.Time `json:"CreatedTime"` + CreatedTime string `json:"CreatedTime"` // Modified from time.Time Datacenter struct { Datacenter struct { Type string `json:"Type"` @@ -59,7 +58,7 @@ type CloudEventReceived struct { } `json:"Vm"` } `json:"Vm"` ConfigSpec *json.RawMessage `json:"configSpec"` - ConfigChanges *ConfigChangesReceived `json:"configChanges"` + ConfigChanges *ConfigChangesReceived `json:"configChanges"` // Modified to separate struct } `json:"data"` } `json:"cloudEvent"` }