diff --git a/logic/hosts.go b/logic/hosts.go index 0b995b16..addb8dc0 100644 --- a/logic/hosts.go +++ b/logic/hosts.go @@ -395,6 +395,21 @@ func HostExists(h *models.Host) bool { return (err != nil && !database.IsEmptyRecord(err)) || (err == nil) } +// GetHostByNodeID - returns a host if found to have a node's ID, else nil +func GetHostByNodeID(id string) *models.Host { + hosts, err := GetAllHosts() + if err != nil { + return nil + } + for i := range hosts { + h := hosts[i] + if StringSliceContains(h.Nodes, id) { + return &h + } + } + return nil +} + func updatePort(p *int) { *p++ if *p > maxPort { diff --git a/logic/nodes.go b/logic/nodes.go index ba4f4687..4dd52c1e 100644 --- a/logic/nodes.go +++ b/logic/nodes.go @@ -83,8 +83,9 @@ func UpdateNode(currentNode *models.Node, newNode *models.Node) error { // DeleteNode - marks node for deletion (and adds to zombie list) if called by UI or deletes node if called by node func DeleteNode(node *models.Node, purge bool) error { + alreadyDeleted := node.PendingDelete || node.Action == models.NODE_DELETE node.Action = models.NODE_DELETE - if !purge { + if !purge && !alreadyDeleted { newnode := *node newnode.PendingDelete = true if err := UpdateNode(node, &newnode); err != nil { @@ -93,8 +94,15 @@ func DeleteNode(node *models.Node, purge bool) error { newZombie <- node.ID return nil } + if alreadyDeleted { + logger.Log(1, "forcibly deleting node", node.ID.String()) + } host, err := GetHost(node.HostID.String()) if err != nil { + logger.Log(1, "no host found for node", node.ID.String(), "deleting..") + if delErr := deleteNodeByID(node); delErr != nil { + logger.Log(0, "failed to delete node", node.ID.String(), delErr.Error()) + } return err } if err := DissasociateNodeFromHost(node, host); err != nil { diff --git a/mq/handlers.go b/mq/handlers.go index 379fbfc2..63095353 100644 --- a/mq/handlers.go +++ b/mq/handlers.go @@ -6,6 +6,7 @@ import ( "time" mqtt "github.com/eclipse/paho.mqtt.golang" + "github.com/google/uuid" "github.com/gravitl/netmaker/database" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logic" @@ -31,13 +32,19 @@ func Ping(client mqtt.Client, msg mqtt.Message) { node, err := logic.GetNodeByID(id) if err != nil { logger.Log(3, "mq-ping error getting node: ", err.Error()) - record, err := database.FetchRecord(database.NODES_TABLE_NAME, id) - if err != nil { - logger.Log(3, "error reading database ", err.Error()) - return + if database.IsEmptyRecord(err) { + h := logic.GetHostByNodeID(id) // check if a host is still associated + if h != nil { // inform host that node should be removed + fakeNode := models.Node{} + fakeNode.ID, _ = uuid.Parse(id) + fakeNode.Action = models.NODE_DELETE + fakeNode.PendingDelete = true + if err := NodeUpdate(&fakeNode); err != nil { + logger.Log(0, "failed to inform host", h.Name, h.ID.String(), "to remove node", id, err.Error()) + } + } } - logger.Log(3, "record from database") - logger.Log(3, record) + return } decrypted, decryptErr := decryptMsg(&node, msg.Payload())