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
         //until one is open and then returns it
         node.Address, err = functions.UniqueAddress(networkName)
         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
                 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()
         v := validator.New()
 
 
@@ -112,23 +144,19 @@ func validateNetwork(operation string, network models.Network) error {
         })
         })
 
 
         _ = v.RegisterValidation("localrange_valid", func(fl validator.FieldLevel) bool {
         _ = 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
                 return isvalid
         })
         })
 
 
         _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool {
         _ = 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
 		return isFieldUnique && inCharSet
         })
         })
 
 
         _ = v.RegisterValidation("displayname_unique", func(fl validator.FieldLevel) bool {
         _ = v.RegisterValidation("displayname_unique", func(fl validator.FieldLevel) bool {
                 isFieldUnique, _ := functions.IsNetworkDisplayNameUnique(fl.Field().String())
                 isFieldUnique, _ := functions.IsNetworkDisplayNameUnique(fl.Field().String())
-                return isFieldUnique ||  operation == "update"
+                return isFieldUnique
         })
         })
 
 
         err := v.Struct(network)
         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 {
         if err != nil {
-		returnErrorResponse(w,r,formatError(err, "internal"))
+		returnErrorResponse(w,r,formatError(err, "badrequest"))
                 return
                 return
         }
         }
 
 
@@ -475,9 +503,9 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
                 network.IsLocal = &falsevar
                 network.IsLocal = &falsevar
         }
         }
 
 
-        //err = validateNetwork("create", network)
+        err = validateNetworkCreate(network)
         if err != nil {
         if err != nil {
-                returnErrorResponse(w,r,formatError(err, "internal"))
+                returnErrorResponse(w,r,formatError(err, "badrequest"))
                 return
                 return
         }
         }
 	network.SetDefaults()
 	network.SetDefaults()
@@ -538,7 +566,7 @@ func createAccessKey(w http.ResponseWriter, r *http.Request) {
         if accesskey.Uses == 0 {
         if accesskey.Uses == 0 {
                 accesskey.Uses = 1
                 accesskey.Uses = 1
         }
         }
-	gconf, err := functions.GetGlobalConfig()
+	_, gconf, err := functions.GetGlobalConfig()
         if err != nil {
         if err != nil {
                 returnErrorResponse(w,r,formatError(err, "internal"))
                 returnErrorResponse(w,r,formatError(err, "internal"))
                 return
                 return

+ 2 - 0
controllers/nodeGrpcController.go

@@ -297,6 +297,8 @@ func (s *NodeServiceServer) GetPeers(req *nodepb.GetPeersReq, stream nodepb.Node
 			Peers: &nodepb.PeersResponse{
 			Peers: &nodepb.PeersResponse{
                             Address:  peers[i].Address,
                             Address:  peers[i].Address,
                             Endpoint:  peers[i].Endpoint,
                             Endpoint:  peers[i].Endpoint,
+                            Gatewayrange:  peers[i].GatewayRange,
+                            Isgateway:  peers[i].IsGateway,
                             Publickey:  peers[i].PublicKey,
                             Publickey:  peers[i].PublicKey,
                             Keepalive:  peers[i].KeepAlive,
                             Keepalive:  peers[i].KeepAlive,
                             Listenport:  peers[i].ListenPort,
                             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)
 	err =  ValidateNode("create", networkName, node)
         if err != nil {
         if err != nil {
-                returnErrorResponse(w,r,formatError(err, "internal"))
+                returnErrorResponse(w,r,formatError(err, "badrequest"))
                 return
                 return
         }
         }
 
 
@@ -592,12 +592,12 @@ func createGateway(w http.ResponseWriter, r *http.Request) {
 	nodechange.IsGateway = true
 	nodechange.IsGateway = true
 	nodechange.GatewayRange = gateway.RangeString
 	nodechange.GatewayRange = gateway.RangeString
 	if gateway.PostUp == "" {
 	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 {
 	} else {
 		nodechange.PostUp = gateway.PostUp
 		nodechange.PostUp = gateway.PostUp
 	}
 	}
 	if gateway.PostDown == "" {
 	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 {
 	} else {
 		nodechange.PostDown = gateway.PostDown
 		nodechange.PostDown = gateway.PostDown
 	}
 	}
@@ -746,7 +746,7 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 
 
         err = ValidateNode("update", params["network"], nodechange)
         err = ValidateNode("update", params["network"], nodechange)
         if err != nil {
         if err != nil {
-                returnErrorResponse(w,r,formatError(err, "internal"))
+                returnErrorResponse(w,r,formatError(err, "badrequest"))
                 return
                 return
         }
         }
 
 

+ 9 - 3
controllers/userHttpController.go

@@ -7,6 +7,7 @@ import (
     "github.com/gravitl/netmaker/mongoconn"
     "github.com/gravitl/netmaker/mongoconn"
     "golang.org/x/crypto/bcrypt"
     "golang.org/x/crypto/bcrypt"
     "time"
     "time"
+    "errors"
     "strings"
     "strings"
     "fmt"
     "fmt"
     "context"
     "context"
@@ -444,11 +445,16 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
 
 
 	success, err := DeleteUser(params["username"])
 	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"])
 		json.NewEncoder(w).Encode("Could not delete user " + params["username"])
 		return
 		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.")
 	json.NewEncoder(w).Encode(params["username"] + " deleted.")
 }
 }

+ 10 - 2
docs/TROUBLESHOOTING.md

@@ -1,6 +1,10 @@
 # Netmaker Troubleshooting Help
 # Netmaker Troubleshooting Help
 
 
 ## Client (netclient)
 ## 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
 ### Client fails to install
 
 
@@ -10,12 +14,16 @@
 
 
 
 
 ## Server
 ## Server
+	### Server not added to default network
+	### Global config not found
+
 
 
-## UI
 
 
 ## MongoDB
 ## 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.
 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
 //node has that value for the same field within the network
 
 
 func CreateServerToken(netID string) (string, error) {
 func CreateServerToken(netID string) (string, error) {
-
+	fmt.Println("Creating token.")
         var network models.Network
         var network models.Network
         var accesskey models.AccessKey
         var accesskey models.AccessKey
 
 
@@ -37,14 +37,29 @@ func CreateServerToken(netID string) (string, error) {
                 accesskey.Name = GenKeyName()
                 accesskey.Name = GenKeyName()
                 accesskey.Value = GenKey()
                 accesskey.Value = GenKey()
                 accesskey.Uses = 1
                 accesskey.Uses = 1
-        gconf, errG := GetGlobalConfig()
+        _, gconf, errG := GetGlobalConfig()
         if errG != nil {
         if errG != nil {
                 return "", errG
                 return "", errG
         }
         }
         address := "localhost" + gconf.PortGRPC
         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)
         network.AccessKeys = append(network.AccessKeys, accesskey)
 
 
@@ -504,7 +519,9 @@ func UniqueAddress(networkName string) (string, error){
 }
 }
 
 
 //pretty simple get
 //pretty simple get
-func GetGlobalConfig() ( models.GlobalConfig, error) {
+func GetGlobalConfig() (bool, models.GlobalConfig, error) {
+
+	create := false
 
 
         filter := bson.M{}
         filter := bson.M{}
 
 
@@ -518,12 +535,16 @@ func GetGlobalConfig() ( models.GlobalConfig, error) {
 
 
         defer cancel()
         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(err)
                 fmt.Println("Could not get global config")
                 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) {
 func VerifyUserToken(tokenString string) (username string, isadmin bool, err error) {
     claims := &models.UserClaims{}
     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) {
     token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
         return jwtSecretKey, nil
         return jwtSecretKey, nil
     })
     })

+ 20 - 7
main.go

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

+ 2 - 0
models/structs.go

@@ -95,6 +95,8 @@ type PeersResponse struct {
     Endpoint string `json:"endpoint" bson:"endpoint"`
     Endpoint string `json:"endpoint" bson:"endpoint"`
     Address string `json:"address" bson:"address"`
     Address string `json:"address" bson:"address"`
     LocalAddress string `json:"localaddress" bson:"localaddress"`
     LocalAddress string `json:"localaddress" bson:"localaddress"`
+    IsGateway bool `json:"isgateway" bson:"isgateway"`
+    GatewayRange string `json:"gatewayrange" bson:"gatewayrange"`
     ListenPort int32 `json:"listenport" bson:"listenport"`
     ListenPort int32 `json:"listenport" bson:"listenport"`
     KeepAlive int32 `json:"persistentkeepalive" bson:"persistentkeepalive"`
     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 privatekey wgtypes.Key
 	var privkeystring string
 	var privkeystring string
 	var endpoint string
 	var endpoint string
+	var postup string
+	var postdown string
 	var name string
 	var name string
 	var wginterface string
 	var wginterface string
 
 
@@ -274,6 +276,17 @@ func Install(accesskey string, password string, server string, network string, n
         }
         }
        fmt.Println("     Interface: " + wginterface)
        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 {
        if nodecfg.KeepAlive != 0 {
                 keepalive = nodecfg.KeepAlive
                 keepalive = nodecfg.KeepAlive
         }
         }
@@ -347,6 +360,8 @@ func Install(accesskey string, password string, server string, network string, n
                 Accesskey: accesskey,
                 Accesskey: accesskey,
                 Nodenetwork:  network,
                 Nodenetwork:  network,
                 Listenport: listenport,
                 Listenport: listenport,
+                Postup: postup,
+                Postdown: postdown,
                 Keepalive: keepalive,
                 Keepalive: keepalive,
 		Localaddress: localaddress,
 		Localaddress: localaddress,
 		Interface: wginterface,
 		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("     Local Address: " + node.Localaddress)
        fmt.Println("     Name: " + node.Name)
        fmt.Println("     Name: " + node.Name)
        fmt.Println("     Interface: " + node.Interface)
        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("     Port: " + strconv.FormatInt(int64(node.Listenport), 10))
        fmt.Println("     KeepAlive: " + strconv.FormatInt(int64(node.Keepalive), 10))
        fmt.Println("     KeepAlive: " + strconv.FormatInt(int64(node.Keepalive), 10))
        fmt.Println("     Public Key: " + node.Publickey)
        fmt.Println("     Public Key: " + node.Publickey)
@@ -483,6 +500,12 @@ func modConfig(node *nodepb.Node) error{
         if node.Localaddress != ""{
         if node.Localaddress != ""{
 		nodecfg.LocalAddress = node.Localaddress
 		nodecfg.LocalAddress = node.Localaddress
         }
         }
+        if node.Postup != ""{
+                nodecfg.PostUp = node.Postup
+        }
+        if node.Postdown != ""{
+                nodecfg.PostDown = node.Postdown
+        }
         if node.Listenport != 0{
         if node.Listenport != 0{
                 nodecfg.Port = node.Listenport
                 nodecfg.Port = node.Listenport
         }
         }
@@ -655,12 +678,41 @@ func initWireguard(node *nodepb.Node, privkey string, peers []wgtypes.PeerConfig
                 Stderr: os.Stdout,
                 Stderr: os.Stdout,
         }
         }
         err = cmdIPLinkDown.Run()
         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
         }
         }
 	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 {
 func setWGKeyConfig(network string, serveraddr string) error {
 
 
@@ -936,7 +988,7 @@ func CheckIn(network string) error {
                 if ifaceupdate {
                 if ifaceupdate {
 			fmt.Println("Interface update: " + currentiface +
 			fmt.Println("Interface update: " + currentiface +
 			" >>>> " + newinterface)
 			" >>>> " + newinterface)
-                        err := DeleteInterface(currentiface)
+                        err := DeleteInterface(currentiface, nodecfg.PostDown)
                         if err != nil {
                         if err != nil {
                                 fmt.Println("ERROR DELETING INTERFACE: " + currentiface)
                                 fmt.Println("ERROR DELETING INTERFACE: " + currentiface)
                         }
                         }
@@ -1183,12 +1235,19 @@ func WipeLocal(network string) error{
         if  err  !=  nil {
         if  err  !=  nil {
                 fmt.Println(err)
                 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
 	return err
 
 
 }
 }
 
 
-func DeleteInterface(ifacename string) error{
+func DeleteInterface(ifacename string, postdown string) error{
         ipExec, err := exec.LookPath("ip")
         ipExec, err := exec.LookPath("ip")
 
 
         cmdIPLinkDel := &exec.Cmd {
         cmdIPLinkDel := &exec.Cmd {
@@ -1201,6 +1260,13 @@ func DeleteInterface(ifacename string) error{
         if  err  !=  nil {
         if  err  !=  nil {
                 fmt.Println(err)
                 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
         return err
 }
 }
 
 
@@ -1260,7 +1326,7 @@ func getPeers(macaddress string, network string, server string) ([]wgtypes.PeerC
                         fmt.Println(err)
                         fmt.Println(err)
 			break
 			break
                 }
                 }
-			spew.Dump(res)
+		spew.Dump(res)
 
 
                 // if err, return an error
                 // if err, return an error
                 if err != nil {
                 if err != nil {
@@ -1272,6 +1338,13 @@ func getPeers(macaddress string, network string, server string) ([]wgtypes.PeerC
                         return peers, err
                         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)
 		pubkey, err := wgtypes.ParseKey(res.Peers.Publickey)
                 if err != nil {
                 if err != nil {
 			fmt.Println("error parsing key")
 			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("NOT SETTING GATEWAY")
 				fmt.Println(err)
 				fmt.Println(err)
 			} else {
 			} else {
+				fmt.Println("    Gateway Range: "  + res.Peers.Gatewayrange)
 				allowedips = append(allowedips, *ipnet)
 				allowedips = append(allowedips, *ipnet)
 			}
 			}
 		}
 		}

+ 1 - 0
netclient/main.go

@@ -110,6 +110,7 @@ func main() {
 			fmt.Println("Beginning agent installation.")
 			fmt.Println("Beginning agent installation.")
 			err := functions.Install(*taccesskey, *tpassword, *tserver, *tnetwork, *tnoauto, *taccesstoken, *tname)
 			err := functions.Install(*taccesskey, *tpassword, *tserver, *tnetwork, *tnoauto, *taccesstoken, *tname)
 			if err != nil {
 			if err != nil {
+				fmt.Println("Error encountered while installing.")
 				if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
 				if !strings.Contains(err.Error(), "ALREADY_INSTALLED") {
 				fmt.Println("Error installing: ", err)
 				fmt.Println("Error installing: ", err)
 				fmt.Println("Cleaning up (uninstall)")
 				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"
         "fmt"
   "github.com/gravitl/netmaker/functions"
   "github.com/gravitl/netmaker/functions"
 	"io"
 	"io"
+	"errors"
 	"net/http"
 	"net/http"
         "os"
         "os"
         "os/exec"
         "os/exec"
@@ -15,6 +16,7 @@ func DownloadNetclient() error {
 	// Get the data
 	// Get the data
 	resp, err := http.Get("https://github.com/gravitl/netmaker/releases/download/latest/netclient")
 	resp, err := http.Get("https://github.com/gravitl/netmaker/releases/download/latest/netclient")
 	if err != nil {
 	if err != nil {
+                fmt.Println("could not download netclient")
 		return err
 		return err
 	}
 	}
 	defer resp.Body.Close()
 	defer resp.Body.Close()
@@ -22,6 +24,7 @@ func DownloadNetclient() error {
 	// Create the file
 	// Create the file
 	out, err := os.Create("/etc/netclient/netclient")
 	out, err := os.Create("/etc/netclient/netclient")
 	if err != nil {
 	if err != nil {
+                fmt.Println("could not create /etc/netclient")
 		return err
 		return err
 	}
 	}
 	defer out.Close()
 	defer out.Close()
@@ -33,6 +36,7 @@ func DownloadNetclient() error {
 func RemoveNetwork(network string) (bool, error) {
 func RemoveNetwork(network string) (bool, error) {
 	_, err := os.Stat("/etc/netclient/netclient")
 	_, err := os.Stat("/etc/netclient/netclient")
         if err != nil {
         if err != nil {
+                fmt.Println("could not find /etc/netclient")
 		return false, err
 		return false, err
 	}
 	}
         cmdoutput, err := exec.Command("/etc/netclient/netclient","-c","remove","-n",network).Output()
         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) {
         if os.IsNotExist(err) {
                 os.Mkdir("/etc/netclient", 744)
                 os.Mkdir("/etc/netclient", 744)
         } else if err != nil {
         } else if err != nil {
-                fmt.Println("couldnt find or create /etc/netclient")
+                fmt.Println("could not find or create /etc/netclient")
                 return false, err
                 return false, err
         }
         }
+	fmt.Println("Directory is ready.")
 	token, err := functions.CreateServerToken(network)
 	token, err := functions.CreateServerToken(network)
         if err != nil {
         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")
         _, err = os.Stat("/etc/netclient/netclient")
 	if os.IsNotExist(err) {
 	if os.IsNotExist(err) {
 		err = DownloadNetclient()
 		err = DownloadNetclient()
+                fmt.Println("could not download netclient")
 		if err != nil {
 		if err != nil {
 			return false, err
 			return false, err
 		}
 		}
 	}
 	}
         err = os.Chmod("/etc/netclient/netclient", 0755)
         err = os.Chmod("/etc/netclient/netclient", 0755)
         if err != nil {
         if err != nil {
+                fmt.Println("could not change netclient directory permissions")
                 return false, err
                 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 {
 	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)
 	fmt.Println("Server added to network " + network)
 	return true, err
 	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