Browse Source

Merge pull request #96 from gravitl/bugfix_v0.2_site2site

Bugfix v0.2 site2site
Alex 4 years ago
parent
commit
5c05db755d

+ 1 - 5
controllers/common.go

@@ -300,11 +300,7 @@ func CreateNode(node models.Node, networkName string) (models.Node, error) {
         //until one is open and then returns it
         node.Address, err = functions.UniqueAddress(networkName)
 
-        if err != nil {/*
-		errorResponse := models.ErrorResponse{
-                        Code: http.StatusInternalServerError, Message: "W1R3: Encountered an internal error! ",
-                }*/
-                //returnErrorResponse(w, r, errorResponse)
+        if err != nil {
                 return node, err
         }
 

+ 42 - 14
controllers/networkHttpController.go

@@ -102,7 +102,39 @@ func getNetworks(w http.ResponseWriter, r *http.Request) {
 	}
 }
 
-func validateNetwork(operation string, network models.Network) error {
+func validateNetworkUpdate(network models.Network) error {
+
+        v := validator.New()
+
+        _ = v.RegisterValidation("addressrange_valid", func(fl validator.FieldLevel) bool {
+                isvalid := fl.Field().String() == "" || functions.IsIpv4CIDR(fl.Field().String())
+                return isvalid
+        })
+
+        _ = v.RegisterValidation("localrange_valid", func(fl validator.FieldLevel) bool {
+                isvalid := fl.Field().String() == "" || functions.IsIpv4CIDR(fl.Field().String())
+                return isvalid
+        })
+
+        _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool {
+                return true
+        })
+
+        _ = v.RegisterValidation("displayname_unique", func(fl validator.FieldLevel) bool {
+                return true
+        })
+
+        err := v.Struct(network)
+
+        if err != nil {
+                for _, e := range err.(validator.ValidationErrors) {
+                        fmt.Println(e)
+                }
+        }
+        return err
+}
+
+func validateNetworkCreate(network models.Network) error {
 
         v := validator.New()
 
@@ -112,23 +144,19 @@ func validateNetwork(operation string, network models.Network) error {
         })
 
         _ = v.RegisterValidation("localrange_valid", func(fl validator.FieldLevel) bool {
-                isvalid := !*network.IsLocal || functions.IsIpv4CIDR(fl.Field().String())
+                isvalid := fl.Field().String() == "" || functions.IsIpv4CIDR(fl.Field().String())
                 return isvalid
         })
 
         _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool {
-		isFieldUnique := false
-		inCharSet := false
-		if operation == "update" { isFieldUnique = true } else{
-			isFieldUnique, _ = functions.IsNetworkNameUnique(fl.Field().String())
-			inCharSet        = functions.NameInNetworkCharSet(fl.Field().String())
-		}
+		isFieldUnique, _ := functions.IsNetworkNameUnique(fl.Field().String())
+		inCharSet        := functions.NameInNetworkCharSet(fl.Field().String())
 		return isFieldUnique && inCharSet
         })
 
         _ = v.RegisterValidation("displayname_unique", func(fl validator.FieldLevel) bool {
                 isFieldUnique, _ := functions.IsNetworkDisplayNameUnique(fl.Field().String())
-                return isFieldUnique ||  operation == "update"
+                return isFieldUnique
         })
 
         err := v.Struct(network)
@@ -281,9 +309,9 @@ func updateNetwork(w http.ResponseWriter, r *http.Request) {
 	}
 
 
-        //err = validateNetwork("update", networkChange)
+        err = validateNetworkUpdate(networkChange)
         if err != nil {
-		returnErrorResponse(w,r,formatError(err, "internal"))
+		returnErrorResponse(w,r,formatError(err, "badrequest"))
                 return
         }
 
@@ -475,9 +503,9 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
                 network.IsLocal = &falsevar
         }
 
-        //err = validateNetwork("create", network)
+        err = validateNetworkCreate(network)
         if err != nil {
-                returnErrorResponse(w,r,formatError(err, "internal"))
+                returnErrorResponse(w,r,formatError(err, "badrequest"))
                 return
         }
 	network.SetDefaults()
@@ -538,7 +566,7 @@ func createAccessKey(w http.ResponseWriter, r *http.Request) {
         if accesskey.Uses == 0 {
                 accesskey.Uses = 1
         }
-	gconf, err := functions.GetGlobalConfig()
+	_, gconf, err := functions.GetGlobalConfig()
         if err != nil {
                 returnErrorResponse(w,r,formatError(err, "internal"))
                 return

+ 2 - 0
controllers/nodeGrpcController.go

@@ -297,6 +297,8 @@ func (s *NodeServiceServer) GetPeers(req *nodepb.GetPeersReq, stream nodepb.Node
 			Peers: &nodepb.PeersResponse{
                             Address:  peers[i].Address,
                             Endpoint:  peers[i].Endpoint,
+                            Gatewayrange:  peers[i].GatewayRange,
+                            Isgateway:  peers[i].IsGateway,
                             Publickey:  peers[i].PublicKey,
                             Keepalive:  peers[i].KeepAlive,
                             Listenport:  peers[i].ListenPort,

+ 4 - 4
controllers/nodeHttpController.go

@@ -500,7 +500,7 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 
 	err =  ValidateNode("create", networkName, node)
         if err != nil {
-                returnErrorResponse(w,r,formatError(err, "internal"))
+                returnErrorResponse(w,r,formatError(err, "badrequest"))
                 return
         }
 
@@ -592,12 +592,12 @@ func createGateway(w http.ResponseWriter, r *http.Request) {
 	nodechange.IsGateway = true
 	nodechange.GatewayRange = gateway.RangeString
 	if gateway.PostUp == "" {
-		nodechange.PostUp = "iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o " + gateway.Interface + " -j MASQUERADE"
+		nodechange.PostUp = "iptables -A FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -A POSTROUTING -o " + gateway.Interface + " -j MASQUERADE"
 	} else {
 		nodechange.PostUp = gateway.PostUp
 	}
 	if gateway.PostDown == "" {
-		nodechange.PostDown = "iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o " + gateway.Interface + " -j MASQUERADE"
+		nodechange.PostDown = "iptables -D FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -D POSTROUTING -o " + gateway.Interface + " -j MASQUERADE"
 	} else {
 		nodechange.PostDown = gateway.PostDown
 	}
@@ -746,7 +746,7 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 
         err = ValidateNode("update", params["network"], nodechange)
         if err != nil {
-                returnErrorResponse(w,r,formatError(err, "internal"))
+                returnErrorResponse(w,r,formatError(err, "badrequest"))
                 return
         }
 

+ 9 - 3
controllers/userHttpController.go

@@ -7,6 +7,7 @@ import (
     "github.com/gravitl/netmaker/mongoconn"
     "golang.org/x/crypto/bcrypt"
     "time"
+    "errors"
     "strings"
     "fmt"
     "context"
@@ -444,11 +445,16 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
 
 	success, err := DeleteUser(params["username"])
 
-	if err != nil || !success {
-		http.Error(w, err.Error(), 400)
+	if err != nil {
+                returnErrorResponse(w, r, formatError(err, "internal"))
 		json.NewEncoder(w).Encode("Could not delete user " + params["username"])
 		return
-	}
+	} else if !success {
+                returnErrorResponse(w, r, formatError(errors.New("Delete unsuccessful."), "internal"))
+                json.NewEncoder(w).Encode("Could not delete user " + params["username"])
+                return
+        }
+
 
 	json.NewEncoder(w).Encode(params["username"] + " deleted.")
 }

+ 10 - 2
docs/TROUBLESHOOTING.md

@@ -1,6 +1,10 @@
 # Netmaker Troubleshooting Help
 
 ## Client (netclient)
+	### Problem: netclient-install script not working
+	### Problem: Hanging artifacts from previous install
+	### Problem: Need to change access token settings
+
 
 ### Client fails to install
 
@@ -10,12 +14,16 @@
 
 
 ## Server
+	### Server not added to default network
+	### Global config not found
+
 
-## UI
 
 ## MongoDB
 
 
 
-## Incorrect backend detected. Please specify correct URL and refresh. Given: http://localhost:8081
+## UI
+
+### Incorrect backend detected. Please specify correct URL and refresh. Given: http://localhost:8081
 Solution: Front end expects a reachable address for the backend. Localhost is default. Check if server is up. If server is up, make sure you've got the right endpoint (endpoint of server. Will not be 'localhost' unless doing local testing). If server is up and endpoint is correct, check for port blockings.

+ 29 - 8
functions/helpers.go

@@ -25,7 +25,7 @@ import (
 //node has that value for the same field within the network
 
 func CreateServerToken(netID string) (string, error) {
-
+	fmt.Println("Creating token.")
         var network models.Network
         var accesskey models.AccessKey
 
@@ -37,14 +37,29 @@ func CreateServerToken(netID string) (string, error) {
                 accesskey.Name = GenKeyName()
                 accesskey.Value = GenKey()
                 accesskey.Uses = 1
-        gconf, errG := GetGlobalConfig()
+        _, gconf, errG := GetGlobalConfig()
         if errG != nil {
                 return "", errG
         }
         address := "localhost" + gconf.PortGRPC
 
-        accessstringdec := address + "." + netID + "." + accesskey.Value
-        accesskey.AccessString = base64.StdEncoding.EncodeToString([]byte(accessstringdec))
+        privAddr := ""
+        if *network.IsLocal {
+                privAddr = network.LocalRange
+        }
+
+
+	fmt.Println("Token details:")
+	fmt.Println("    grpc address + port: " + address)
+	fmt.Println("                network: " + netID)
+	fmt.Println("          private range: " + privAddr)
+
+	accessstringdec := address + "|" + netID + "|" + accesskey.Value + "|" + privAddr
+
+	accesskey.AccessString = base64.StdEncoding.EncodeToString([]byte(accessstringdec))
+
+        fmt.Println("          access string: " + accesskey.AccessString)
+
 
         network.AccessKeys = append(network.AccessKeys, accesskey)
 
@@ -504,7 +519,9 @@ func UniqueAddress(networkName string) (string, error){
 }
 
 //pretty simple get
-func GetGlobalConfig() ( models.GlobalConfig, error) {
+func GetGlobalConfig() (bool, models.GlobalConfig, error) {
+
+	create := false
 
         filter := bson.M{}
 
@@ -518,12 +535,16 @@ func GetGlobalConfig() ( models.GlobalConfig, error) {
 
         defer cancel()
 
-        if err != nil {
+	if err == mongo.ErrNoDocuments {
+                fmt.Println("Global config does not exist. Need to create.")
+		create = true
+		return create, globalconf, err
+	} else if err != nil {
                 fmt.Println(err)
                 fmt.Println("Could not get global config")
-                return globalconf, err
+                return create, globalconf, err
         }
-	return globalconf, err
+	return create, globalconf, err
 }
 
 

+ 4 - 0
functions/jwt.go

@@ -50,6 +50,10 @@ func CreateUserJWT(username string, isadmin bool) (response string, err error) {
 func VerifyUserToken(tokenString string) (username string, isadmin bool, err error) {
     claims := &models.UserClaims{}
 
+    if tokenString == config.Config.Server.MasterKey {
+        return "masteradministrator", true, nil
+    }
+
     token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
         return jwtSecretKey, nil
     })

+ 20 - 7
main.go

@@ -16,6 +16,7 @@ import (
     "fmt"
     "time"
     "net/http"
+    "strings"
     "errors"
     "io/ioutil"
     "os"
@@ -25,6 +26,7 @@ import (
     "strconv"
     "sync"
     "os/signal"
+    "go.mongodb.org/mongo-driver/mongo"
     service "github.com/gravitl/netmaker/controllers"
     nodepb "github.com/gravitl/netmaker/grpc"
     "google.golang.org/grpc"
@@ -61,6 +63,7 @@ func main() {
 
 	log.Println("Server starting...")
 	mongoconn.ConnectDatabase()
+
 	installserver := false
 	if !(defaultnet == "off") {
 	if config.Config.Server.CreateDefault {
@@ -127,7 +130,7 @@ func runGRPC(wg *sync.WaitGroup, installserver bool) {
 	gconf.Name = "netmaker"
 	err := setGlobalConfig(gconf)
 
-	if err != nil {
+	if err != nil && err != mongo.ErrNoDocuments{
 	      log.Fatalf("Unable to set global config: %v", err)
 	}
 
@@ -159,11 +162,13 @@ func runGRPC(wg *sync.WaitGroup, installserver bool) {
         fmt.Println("Agent Server succesfully started on port " + grpcport + " (gRPC)")
 
 	if installserver {
-			fmt.Println("Adding server to default network")
+			fmt.Println("Adding server to " + config.Config.Server.DefaultNetName)
                         success, err := serverctl.AddNetwork(config.Config.Server.DefaultNetName)
                         if err != nil || !success {
                                 fmt.Printf("Error adding to default network: %v", err)
+				fmt.Println("")
 				fmt.Println("Unable to add server to network. Continuing.")
+				fmt.Println("Please investigate client installation on server.")
 			} else {
                                 fmt.Println("Server successfully added to default network.")
 			}
@@ -198,12 +203,16 @@ func setGlobalConfig(globalconf models.GlobalConfig) (error) {
         collection := mongoconn.Client.Database("netmaker").Collection("config")
         ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 
-	_, err := functions.GetGlobalConfig()
-	if err != nil {
+	create, _, err := functions.GetGlobalConfig()
+	if create {
 		_, err := collection.InsertOne(ctx, globalconf)
 		defer cancel()
 		if err != nil {
-			return err
+			if err == mongo.ErrNoDocuments || strings.Contains(err.Error(), "no documents in result"){
+				return nil
+			} else {
+				return err
+			}
 		}
 	} else {
 		filter := bson.M{"name": "netmaker"}
@@ -213,9 +222,13 @@ func setGlobalConfig(globalconf models.GlobalConfig) (error) {
 				{"portgrpc", globalconf.PortGRPC},
 			}},
 		}
-		err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&globalconf)
+		err := collection.FindOneAndUpdate(ctx, filter, update).Decode(&globalconf)
+                        if err == mongo.ErrNoDocuments {
+			//if err == mongo.ErrNoDocuments || strings.Contains(err.Error(), "no documents in result"){
+                                return nil
+                        }
 	}
-	return nil
+	return err
 }
 
 func createDefaultNetwork() (bool, error) {

+ 2 - 0
models/structs.go

@@ -95,6 +95,8 @@ type PeersResponse struct {
     Endpoint string `json:"endpoint" bson:"endpoint"`
     Address string `json:"address" bson:"address"`
     LocalAddress string `json:"localaddress" bson:"localaddress"`
+    IsGateway bool `json:"isgateway" bson:"isgateway"`
+    GatewayRange string `json:"gatewayrange" bson:"gatewayrange"`
     ListenPort int32 `json:"listenport" bson:"listenport"`
     KeepAlive int32 `json:"persistentkeepalive" bson:"persistentkeepalive"`
 }

+ 79 - 5
netclient/functions/common.go

@@ -196,6 +196,8 @@ func Install(accesskey string, password string, server string, network string, n
 	var privatekey wgtypes.Key
 	var privkeystring string
 	var endpoint string
+	var postup string
+	var postdown string
 	var name string
 	var wginterface string
 
@@ -274,6 +276,17 @@ func Install(accesskey string, password string, server string, network string, n
         }
        fmt.Println("     Interface: " + wginterface)
 
+        if nodecfg.PostUp != "" {
+                postup = nodecfg.PostUp
+        }
+       fmt.Println("     PostUp: " + postup)
+
+       if nodecfg.PostDown!= "" {
+                postdown = nodecfg.PostDown
+        }
+       fmt.Println("     PostDown: " + postdown)
+
+
        if nodecfg.KeepAlive != 0 {
                 keepalive = nodecfg.KeepAlive
         }
@@ -347,6 +360,8 @@ func Install(accesskey string, password string, server string, network string, n
                 Accesskey: accesskey,
                 Nodenetwork:  network,
                 Listenport: listenport,
+                Postup: postup,
+                Postdown: postdown,
                 Keepalive: keepalive,
 		Localaddress: localaddress,
 		Interface: wginterface,
@@ -384,6 +399,8 @@ func Install(accesskey string, password string, server string, network string, n
        fmt.Println("     Local Address: " + node.Localaddress)
        fmt.Println("     Name: " + node.Name)
        fmt.Println("     Interface: " + node.Interface)
+       fmt.Println("     PostUp: " + node.Postup)
+       fmt.Println("     PostDown: " + node.Postdown)
        fmt.Println("     Port: " + strconv.FormatInt(int64(node.Listenport), 10))
        fmt.Println("     KeepAlive: " + strconv.FormatInt(int64(node.Keepalive), 10))
        fmt.Println("     Public Key: " + node.Publickey)
@@ -483,6 +500,12 @@ func modConfig(node *nodepb.Node) error{
         if node.Localaddress != ""{
 		nodecfg.LocalAddress = node.Localaddress
         }
+        if node.Postup != ""{
+                nodecfg.PostUp = node.Postup
+        }
+        if node.Postdown != ""{
+                nodecfg.PostDown = node.Postdown
+        }
         if node.Listenport != 0{
                 nodecfg.Port = node.Listenport
         }
@@ -655,12 +678,41 @@ func initWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
                 Stderr: os.Stdout,
         }
         err = cmdIPLinkDown.Run()
-        err = cmdIPLinkUp.Run()
-        if  err  !=  nil {
+        if nodecfg.PostDown != "" {
+		runcmds := strings.Split(nodecfg.PostDown, "; ")
+		err = runCmds(runcmds)
+		if err != nil {
+			fmt.Println("Error encountered running PostDown: " + err.Error())
+		}
+	}
+
+	err = cmdIPLinkUp.Run()
+        if nodecfg.PostUp != "" {
+                runcmds := strings.Split(nodecfg.PostUp, "; ")
+                err = runCmds(runcmds)
+                if err != nil {
+                        fmt.Println("Error encountered running PostUp: " + err.Error())
+                }
+        }
+	if  err  !=  nil {
                 return err
         }
 	return err
 }
+func runCmds(commands []string) error {
+	var err error
+	for _, command := range commands {
+		fmt.Println("Running command: " + command)
+		args := strings.Fields(command)
+		out, err := exec.Command(args[0], args[1:]...).Output()
+		fmt.Println(string(out))
+		if err != nil {
+			return err
+		}
+	}
+	return err
+}
+
 
 func setWGKeyConfig(network string, serveraddr string) error {
 
@@ -936,7 +988,7 @@ func CheckIn(network string) error {
                 if ifaceupdate {
 			fmt.Println("Interface update: " + currentiface +
 			" >>>> " + newinterface)
-                        err := DeleteInterface(currentiface)
+                        err := DeleteInterface(currentiface, nodecfg.PostDown)
                         if err != nil {
                                 fmt.Println("ERROR DELETING INTERFACE: " + currentiface)
                         }
@@ -1183,12 +1235,19 @@ func WipeLocal(network string) error{
         if  err  !=  nil {
                 fmt.Println(err)
         }
+        if nodecfg.PostDown != "" {
+                runcmds := strings.Split(nodecfg.PostDown, "; ")
+                err = runCmds(runcmds)
+                if err != nil {
+                        fmt.Println("Error encountered running PostDown: " + err.Error())
+                }
+        }
 	}
 	return err
 
 }
 
-func DeleteInterface(ifacename string) error{
+func DeleteInterface(ifacename string, postdown string) error{
         ipExec, err := exec.LookPath("ip")
 
         cmdIPLinkDel := &exec.Cmd {
@@ -1201,6 +1260,13 @@ func DeleteInterface(ifacename string) error{
         if  err  !=  nil {
                 fmt.Println(err)
         }
+        if postdown != "" {
+                runcmds := strings.Split(postdown, "; ")
+                err = runCmds(runcmds)
+                if err != nil {
+                        fmt.Println("Error encountered running PostDown: " + err.Error())
+                }
+        }
         return err
 }
 
@@ -1260,7 +1326,7 @@ func getPeers(macaddress string, network string, server string) ([]wgtypes.PeerC
                         fmt.Println(err)
 			break
                 }
-			spew.Dump(res)
+		spew.Dump(res)
 
                 // if err, return an error
                 if err != nil {
@@ -1272,6 +1338,13 @@ func getPeers(macaddress string, network string, server string) ([]wgtypes.PeerC
                         return peers, err
 			}
                 }
+		fmt.Println("Got Peer: "  + res.Peers.Publickey)
+		fmt.Println("    Address: " +res.Peers.Address)
+		fmt.Printf("    ListenPort: ",res.Peers.Listenport)
+		fmt.Println("")
+		fmt.Printf("    Gateway?: ",res.Peers.Isgateway)
+		fmt.Println("")
+                fmt.Println("    Gate Range: " + res.Peers.Gatewayrange)
 		pubkey, err := wgtypes.ParseKey(res.Peers.Publickey)
                 if err != nil {
 			fmt.Println("error parsing key")
@@ -1292,6 +1365,7 @@ func getPeers(macaddress string, network string, server string) ([]wgtypes.PeerC
 				fmt.Println("NOT SETTING GATEWAY")
 				fmt.Println(err)
 			} else {
+				fmt.Println("    Gateway Range: "  + res.Peers.Gatewayrange)
 				allowedips = append(allowedips, *ipnet)
 			}
 		}

+ 1 - 0
netclient/main.go

@@ -110,6 +110,7 @@ func main() {
 			fmt.Println("Beginning agent installation.")
 			err := functions.Install(*taccesskey, *tpassword, *tserver, *tnetwork, *tnoauto, *taccesstoken, *tname)
 			if err != nil {
+				fmt.Println("Error encountered while installing.")
 				if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
 				fmt.Println("Error installing: ", err)
 				fmt.Println("Cleaning up (uninstall)")

+ 1 - 0
privatekey

@@ -0,0 +1 @@
+wMb6dxHPNJqQd8GbwfLN8HPLiJYEl1uJtEls5hRoD10=

+ 1 - 0
publickey

@@ -0,0 +1 @@
+/FdO9q+Bs3ee/NVbtKwMhSmFj4AyyjmlOrujzaBoenE=

+ 15 - 6
serverctl/serverctl.go

@@ -4,6 +4,7 @@ import (
         "fmt"
   "github.com/gravitl/netmaker/functions"
 	"io"
+	"errors"
 	"net/http"
         "os"
         "os/exec"
@@ -15,6 +16,7 @@ func DownloadNetclient() error {
 	// Get the data
 	resp, err := http.Get("https://github.com/gravitl/netmaker/releases/download/latest/netclient")
 	if err != nil {
+                fmt.Println("could not download netclient")
 		return err
 	}
 	defer resp.Body.Close()
@@ -22,6 +24,7 @@ func DownloadNetclient() error {
 	// Create the file
 	out, err := os.Create("/etc/netclient/netclient")
 	if err != nil {
+                fmt.Println("could not create /etc/netclient")
 		return err
 	}
 	defer out.Close()
@@ -33,6 +36,7 @@ func DownloadNetclient() error {
 func RemoveNetwork(network string) (bool, error) {
 	_, err := os.Stat("/etc/netclient/netclient")
         if err != nil {
+                fmt.Println("could not find /etc/netclient")
 		return false, err
 	}
         cmdoutput, err := exec.Command("/etc/netclient/netclient","-c","remove","-n",network).Output()
@@ -50,31 +54,36 @@ func AddNetwork(network string) (bool, error) {
         if os.IsNotExist(err) {
                 os.Mkdir("/etc/netclient", 744)
         } else if err != nil {
-                fmt.Println("couldnt find or create /etc/netclient")
+                fmt.Println("could not find or create /etc/netclient")
                 return false, err
         }
+	fmt.Println("Directory is ready.")
 	token, err := functions.CreateServerToken(network)
         if err != nil {
-                return false, err
+                fmt.Println("could not create server token for " + network)
+		return false, err
         }
+	fmt.Println("Token is ready.")
         _, err = os.Stat("/etc/netclient/netclient")
 	if os.IsNotExist(err) {
 		err = DownloadNetclient()
+                fmt.Println("could not download netclient")
 		if err != nil {
 			return false, err
 		}
 	}
         err = os.Chmod("/etc/netclient/netclient", 0755)
         if err != nil {
+                fmt.Println("could not change netclient directory permissions")
                 return false, err
         }
-	cmdoutput, err := exec.Command("/etc/netclient/netclient","-c","install","-t",token,"-name","netmaker").Output()
+	fmt.Println("Client is ready. Running install.")
+	out, err := exec.Command("/etc/netclient/netclient","-c","install","-t",token,"-name","netmaker").Output()
+        fmt.Println(string(out))
 	if err != nil {
-	        fmt.Println(string(cmdoutput))
-                return false, err
+                return false, errors.New(string(out) + err.Error())
         }
 	fmt.Println("Server added to network " + network)
 	return true, err
 }
 
-

+ 7 - 0
test/restartmongo.sh

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+sudo docker kill mongodb
+sudo docker rm mongodb
+sudo docker volume rm mongovol
+
+docker volume create mongovol && docker run -d --name mongodb -v mongovol:/data/db --network host -e MONGO_INITDB_ROOT_USERNAME=mongoadmin -e MONGO_INITDB_ROOT_PASSWORD=mongopass mongo --bind_ip 0.0.0.0