Browse Source

Merge pull request #702 from gravitl/refactor_v0.10.0_del_seg

refactored delete, pull nil pointer and logging
dcarns 3 years ago
parent
commit
05ada0402a

+ 14 - 0
controllers/auth_grpc.go

@@ -131,15 +131,29 @@ func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.Object) (*nod
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
+		var found = false
 		for _, value := range collection {
 		for _, value := range collection {
 			if err = json.Unmarshal([]byte(value), &result); err != nil {
 			if err = json.Unmarshal([]byte(value), &result); err != nil {
 				continue // finish going through nodes
 				continue // finish going through nodes
 			}
 			}
 			if result.ID == nodeID && result.Network == network {
 			if result.ID == nodeID && result.Network == network {
+				found = true
 				break
 				break
 			}
 			}
 		}
 		}
 
 
+		if !found {
+			deletedNode, err := database.FetchRecord(database.DELETED_NODES_TABLE_NAME, nodeID)
+			if err != nil {
+				err = errors.New("node not found")
+				return nil, err
+			}
+			if err = json.Unmarshal([]byte(deletedNode), &result); err != nil {
+				err = errors.New("node data corrupted")
+				return nil, err
+			}
+		}
+
 		//compare password from request to stored password in database
 		//compare password from request to stored password in database
 		//might be able to have a common hash (certificates?) and compare those so that a password isn't passed in in plain text...
 		//might be able to have a common hash (certificates?) and compare those so that a password isn't passed in in plain text...
 		//TODO: Consider a way of hashing the password client side before sending, or using certificates
 		//TODO: Consider a way of hashing the password client side before sending, or using certificates

+ 7 - 4
controllers/node.go

@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"fmt"
 	"net/http"
 	"net/http"
 	"strings"
 	"strings"
+	"time"
 
 
 	"github.com/gorilla/mux"
 	"github.com/gorilla/mux"
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/database"
@@ -599,20 +600,22 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 	//send update to node to be deleted before deleting on server otherwise message cannot be sent
 	//send update to node to be deleted before deleting on server otherwise message cannot be sent
 	node.Action = models.NODE_DELETE
 	node.Action = models.NODE_DELETE
-	runUpdates(&node, true)
-	err = logic.DeleteNodeByID(&node, false)
-	if err != nil {
+	if err := mq.NodeUpdate(&node); err != nil {
+		logger.Log(1, "error publishing node update", err.Error())
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
 
 
+	err = logic.DeleteNodeByID(&node, false)
 	if err != nil {
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
-	logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
 	returnSuccessResponse(w, r, nodeid+" deleted.")
 	returnSuccessResponse(w, r, nodeid+" deleted.")
 
 
+	time.Sleep(time.Second << 1)
+	logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
+	runUpdates(&node, false)
 }
 }
 
 
 func runUpdates(node *models.Node, nodeUpdate bool) error {
 func runUpdates(node *models.Node, nodeUpdate bool) error {

+ 1 - 0
controllers/node_grpc.go

@@ -216,6 +216,7 @@ func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.Object)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
+
 	runServerPeerUpdate(&node, false)
 	runServerPeerUpdate(&node, false)
 
 
 	return &nodepb.Object{
 	return &nodepb.Object{

+ 1 - 1
controllers/node_test.go

@@ -133,7 +133,7 @@ func TestValidateEgressGateway(t *testing.T) {
 		gateway.Interface = ""
 		gateway.Interface = ""
 		err := logic.ValidateEgressGateway(gateway)
 		err := logic.ValidateEgressGateway(gateway)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
-		assert.Equal(t, "Interface cannot be empty", err.Error())
+		assert.Equal(t, "interface cannot be empty", err.Error())
 	})
 	})
 	t.Run("Success", func(t *testing.T) {
 	t.Run("Success", func(t *testing.T) {
 		gateway.Interface = "eth0"
 		gateway.Interface = "eth0"

+ 1 - 1
logic/gateway.go

@@ -72,7 +72,7 @@ func ValidateEgressGateway(gateway models.EgressGatewayRequest) error {
 	}
 	}
 	empty = gateway.Interface == ""
 	empty = gateway.Interface == ""
 	if empty {
 	if empty {
-		err = errors.New("Interface cannot be empty")
+		err = errors.New("interface cannot be empty")
 	}
 	}
 	return err
 	return err
 }
 }

+ 0 - 33
logic/util.go

@@ -64,39 +64,6 @@ func IsAddressInCIDR(address, cidr string) bool {
 	return currentCIDR.Contains(ip)
 	return currentCIDR.Contains(ip)
 }
 }
 
 
-// DeleteNodeByMacAddress - deletes a node from database or moves into delete nodes table
-func DeleteNodeByMacAddress(node *models.Node, exterminate bool) error {
-	var err error
-	var key = node.ID
-	if !exterminate {
-		args := strings.Split(key, "###")
-		node, err := GetNodeByMacAddress(args[0], args[1])
-		if err != nil {
-			return err
-		}
-		node.Action = models.NODE_DELETE
-		nodedata, err := json.Marshal(&node)
-		if err != nil {
-			return err
-		}
-		err = database.Insert(key, string(nodedata), database.DELETED_NODES_TABLE_NAME)
-		if err != nil {
-			return err
-		}
-	} else {
-		if err := database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, key); err != nil {
-			logger.Log(2, err.Error())
-		}
-	}
-	if err = database.DeleteRecord(database.NODES_TABLE_NAME, key); err != nil {
-		return err
-	}
-	if servercfg.IsDNSMode() {
-		SetDNS()
-	}
-	return removeLocalServer(node)
-}
-
 // SetNetworkNodesLastModified - sets the network nodes last modified
 // SetNetworkNodesLastModified - sets the network nodes last modified
 func SetNetworkNodesLastModified(networkName string) error {
 func SetNetworkNodesLastModified(networkName string) error {
 
 

+ 21 - 0
netclient/daemon/common.go

@@ -31,6 +31,7 @@ func InstallDaemon(cfg config.ClientConfig) error {
 	return err
 	return err
 }
 }
 
 
+// Restart - restarts a system daemon
 func Restart() error {
 func Restart() error {
 	os := runtime.GOOS
 	os := runtime.GOOS
 	var err error
 	var err error
@@ -49,3 +50,23 @@ func Restart() error {
 	}
 	}
 	return err
 	return err
 }
 }
+
+// Stop - stops a system daemon
+func Stop() error {
+	os := runtime.GOOS
+	var err error
+
+	time.Sleep(time.Second)
+
+	switch os {
+	case "windows":
+		StopWindowsDaemon()
+	case "darwin":
+		StopLaunchD()
+	case "linux":
+		StopSystemD()
+	default:
+		err = errors.New("no OS daemon to stop")
+	}
+	return err
+}

+ 6 - 0
netclient/daemon/macos.go

@@ -56,12 +56,18 @@ func CleanupMac() {
 	os.Remove(MAC_EXEC_DIR + "netclient")
 	os.Remove(MAC_EXEC_DIR + "netclient")
 }
 }
 
 
+// RestartLaunchD - restart launch daemon
 func RestartLaunchD() {
 func RestartLaunchD() {
 	ncutils.RunCmd("launchctl unload /Library/LaunchDaemons/"+MAC_SERVICE_NAME+".plist", true)
 	ncutils.RunCmd("launchctl unload /Library/LaunchDaemons/"+MAC_SERVICE_NAME+".plist", true)
 	time.Sleep(time.Second >> 2)
 	time.Sleep(time.Second >> 2)
 	ncutils.RunCmd("launchctl load /Library/LaunchDaemons/"+MAC_SERVICE_NAME+".plist", true)
 	ncutils.RunCmd("launchctl load /Library/LaunchDaemons/"+MAC_SERVICE_NAME+".plist", true)
 }
 }
 
 
+// StopLaunchD - stop launch daemon
+func StopLaunchD() {
+	ncutils.RunCmd("launchctl unload  /System/Library/LaunchDaemons/"+MAC_SERVICE_NAME+".plist", true)
+}
+
 // CreateMacService - Creates the mac service file for LaunchDaemons
 // CreateMacService - Creates the mac service file for LaunchDaemons
 func CreateMacService(servicename string, interval string) error {
 func CreateMacService(servicename string, interval string) error {
 	_, err := os.Stat("/Library/LaunchDaemons")
 	_, err := os.Stat("/Library/LaunchDaemons")

+ 7 - 0
netclient/daemon/systemd.go

@@ -74,12 +74,14 @@ WantedBy=multi-user.target
 	return nil
 	return nil
 }
 }
 
 
+// RestartSystemD - restarts systemd service
 func RestartSystemD() {
 func RestartSystemD() {
 	ncutils.PrintLog("restarting netclient.service", 1)
 	ncutils.PrintLog("restarting netclient.service", 1)
 	time.Sleep(time.Second)
 	time.Sleep(time.Second)
 	_, _ = ncutils.RunCmd("systemctl restart netclient.service", true)
 	_, _ = ncutils.RunCmd("systemctl restart netclient.service", true)
 }
 }
 
 
+// CleanupLinux - cleans up neclient configs
 func CleanupLinux() {
 func CleanupLinux() {
 	if err := os.RemoveAll(ncutils.GetNetclientPath()); err != nil {
 	if err := os.RemoveAll(ncutils.GetNetclientPath()); err != nil {
 		ncutils.PrintLog("Removing netclient configs: "+err.Error(), 1)
 		ncutils.PrintLog("Removing netclient configs: "+err.Error(), 1)
@@ -89,6 +91,11 @@ func CleanupLinux() {
 	}
 	}
 }
 }
 
 
+// StopSystemD - tells system to stop systemd
+func StopSystemD() {
+	ncutils.RunCmd("systemctl stop netclient.service", false)
+}
+
 // RemoveSystemDServices - removes the systemd services on a machine
 // RemoveSystemDServices - removes the systemd services on a machine
 func RemoveSystemDServices() error {
 func RemoveSystemDServices() error {
 	//sysExec, err := exec.LookPath("systemctl")
 	//sysExec, err := exec.LookPath("systemctl")

+ 0 - 3
netclient/functions/checkin.go

@@ -248,9 +248,6 @@ func Pull(network string, manual bool) (*models.Node, error) {
 			}
 			}
 		}
 		}
 	}
 	}
-	//if ncutils.IsLinux() {
-	//	setDNS(&resNode, servercfg, &cfg.Node)
-	//}
 	var bkupErr = config.SaveBackup(network)
 	var bkupErr = config.SaveBackup(network)
 	if bkupErr != nil {
 	if bkupErr != nil {
 		ncutils.Log("unable to update backup file")
 		ncutils.Log("unable to update backup file")

+ 1 - 0
netclient/functions/common.go

@@ -219,6 +219,7 @@ func LeaveNetwork(network string) error {
 
 
 	currentNets, err := ncutils.GetSystemNetworks()
 	currentNets, err := ncutils.GetSystemNetworks()
 	if err != nil || len(currentNets) <= 1 {
 	if err != nil || len(currentNets) <= 1 {
+		daemon.Stop() // stop system daemon if last network
 		return RemoveLocalInstance(cfg, network)
 		return RemoveLocalInstance(cfg, network)
 	}
 	}
 	return daemon.Restart()
 	return daemon.Restart()

+ 9 - 17
netclient/functions/daemon.go

@@ -105,17 +105,16 @@ func SetupMQTT(cfg *config.ClientConfig) mqtt.Client {
 				ncutils.Log("could not run pull, exiting " + cfg.Node.Network + " setup: " + err.Error())
 				ncutils.Log("could not run pull, exiting " + cfg.Node.Network + " setup: " + err.Error())
 				return client
 				return client
 			}
 			}
-			time.Sleep(2 * time.Second)
+			time.Sleep(time.Second)
 		}
 		}
 		if token := client.Connect(); token.Wait() && token.Error() != nil {
 		if token := client.Connect(); token.Wait() && token.Error() != nil {
 			ncutils.Log("unable to connect to broker, retrying ...")
 			ncutils.Log("unable to connect to broker, retrying ...")
 			if time.Now().After(tperiod) {
 			if time.Now().After(tperiod) {
 				ncutils.Log("could not connect to broker, exiting " + cfg.Node.Network + " setup: " + token.Error().Error())
 				ncutils.Log("could not connect to broker, exiting " + cfg.Node.Network + " setup: " + token.Error().Error())
-				if strings.Contains(token.Error().Error(), "connectex") {
-					ncutils.PrintLog("connection issue detected.. restarting daemon", 0)
+				if strings.Contains(token.Error().Error(), "connectex") || strings.Contains(token.Error().Error(), "i/o timeout") {
+					ncutils.PrintLog("connection issue detected.. pulling and restarting daemon", 0)
 					Pull(cfg.Node.Network, true)
 					Pull(cfg.Node.Network, true)
 					daemon.Restart()
 					daemon.Restart()
-					os.Exit(2)
 				}
 				}
 				return client
 				return client
 			}
 			}
@@ -273,30 +272,23 @@ func NodeUpdate(client mqtt.Client, msg mqtt.Message) {
 			} else {
 			} else {
 				ncutils.Log("failed to kill go routines for network " + newNode.Network)
 				ncutils.Log("failed to kill go routines for network " + newNode.Network)
 			}
 			}
-			ncutils.Log("deleting configuration files")
-			if err := WipeLocal(cfg.Network); err != nil {
-				ncutils.PrintLog("error deleting local instance: "+err.Error(), 1)
-				ncutils.PrintLog("Please perform manual clean up", 1)
-			}
-			currNets, err := ncutils.GetSystemNetworks()
-			if err == nil && len(currNets) == 0 {
-				if err = RemoveLocalInstance(&cfg, cfg.Network); err != nil {
-					ncutils.PrintLog("Please perform manual clean up", 1)
+			ncutils.PrintLog(fmt.Sprintf("received delete request for %s", cfg.Node.Name), 1)
+			if err = LeaveNetwork(cfg.Node.Network); err != nil {
+				if !strings.Contains("rpc error", err.Error()) {
+					ncutils.PrintLog(fmt.Sprintf("failed to leave, please check that local files for network %s were removed", cfg.Node.Network), 1)
 				}
 				}
-				os.Exit(0)
 			}
 			}
+			ncutils.PrintLog(fmt.Sprintf("%s was removed", cfg.Node.Name), 1)
 			return
 			return
 		case models.NODE_UPDATE_KEY:
 		case models.NODE_UPDATE_KEY:
-			ncutils.Log("delete recieved")
 			if err := UpdateKeys(&cfg, client); err != nil {
 			if err := UpdateKeys(&cfg, client); err != nil {
 				ncutils.PrintLog("err updating wireguard keys: "+err.Error(), 1)
 				ncutils.PrintLog("err updating wireguard keys: "+err.Error(), 1)
 			}
 			}
 			ifaceDelta = true
 			ifaceDelta = true
 		case models.NODE_NOOP:
 		case models.NODE_NOOP:
-			ncutils.Log("noop recieved")
 		default:
 		default:
 		}
 		}
-		//Save new config
+		// Save new config
 		cfg.Node.Action = models.NODE_NOOP
 		cfg.Node.Action = models.NODE_NOOP
 		if err := config.Write(&cfg, cfg.Network); err != nil {
 		if err := config.Write(&cfg, cfg.Network); err != nil {
 			ncutils.PrintLog("error updating node configuration: "+err.Error(), 1)
 			ncutils.PrintLog("error updating node configuration: "+err.Error(), 1)

+ 6 - 5
netclient/wireguard/common.go

@@ -165,10 +165,11 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 	// ensure you clear any existing interface first
 	// ensure you clear any existing interface first
 	d, _ := wgclient.Device(deviceiface)
 	d, _ := wgclient.Device(deviceiface)
 	for d != nil && d.Name == deviceiface {
 	for d != nil && d.Name == deviceiface {
-		err = RemoveConf(deviceiface, false) // remove interface first
-		if strings.Contains(err.Error(), "does not exist") {
-			err = nil
-			break
+		if err = RemoveConf(deviceiface, false); err != nil { // remove interface first
+			if strings.Contains(err.Error(), "does not exist") {
+				err = nil
+				break
+			}
 		}
 		}
 		time.Sleep(time.Second >> 2)
 		time.Sleep(time.Second >> 2)
 		d, _ = wgclient.Device(deviceiface)
 		d, _ = wgclient.Device(deviceiface)
@@ -201,7 +202,7 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 			return fmt.Errorf("could not reliably create interface, please check wg installation and retry")
 			return fmt.Errorf("could not reliably create interface, please check wg installation and retry")
 		}
 		}
 	}
 	}
-	ncutils.PrintLog("interface ready - netclient engage", 1)
+	ncutils.PrintLog("interface ready - netclient.. ENGAGE", 1)
 	if syncconf { // should never be called really.
 	if syncconf { // should never be called really.
 		err = SyncWGQuickConf(ifacename, confPath)
 		err = SyncWGQuickConf(ifacename, confPath)
 	}
 	}