Browse Source

Mid way through adopting rqlite

afeiszli 4 years ago
parent
commit
93b0b94788

+ 3 - 13
config/config.go

@@ -2,7 +2,6 @@
 //Currently the only thing it does is set the master password
 //Should probably have it take over functions from OS such as port and mongodb connection details
 //Reads from the config/environments/dev.yaml file by default
-//TODO:  Add vars for mongo and remove from  OS vars in mongoconn
 package config
 
 import (
@@ -30,14 +29,13 @@ var Config *EnvironmentConfig
 
 // EnvironmentConfig :
 type EnvironmentConfig struct {
-	Server    ServerConfig    `yaml:"server"`
-	MongoConn MongoConnConfig `yaml:"mongoconn"`
-	WG        WG              `yaml:"wg"`
+	Server ServerConfig `yaml:"server"`
+	WG     WG           `yaml:"wg"`
 }
 
 // ServerConfig :
 type ServerConfig struct {
-	CoreDNSAddr string `yaml:"corednsaddr"`
+	CoreDNSAddr          string `yaml:"corednsaddr"`
 	APIConnString        string `yaml:"apiconn"`
 	APIHost              string `yaml:"apihost"`
 	APIPort              string `yaml:"apiport"`
@@ -69,14 +67,6 @@ type WG struct {
 	GRPCWGPrivKey       string `yaml:"privkey"`
 }
 
-type MongoConnConfig struct {
-	User string `yaml:"user"`
-	Pass string `yaml:"pass"`
-	Host string `yaml:"host"`
-	Port string `yaml:"port"`
-	Opts string `yaml:"opts"`
-}
-
 //reading in the env file
 func readConfig() *EnvironmentConfig {
 	file := fmt.Sprintf("config/environments/%s.yaml", getEnv())

+ 0 - 6
config/environments/dev.yaml

@@ -10,12 +10,6 @@ server:
   clientmode: "" # defaults to "on" or CLIENT_MODE (if set)
   dnsmode: "" # defaults to "on" or DNS_MODE (if set)
   disableremoteipcheck: "" # defaults to "false" or DISABLE_REMOTE_IP_CHECK (if set)
-mongoconn:
-  user: "" # defaults to "mongoadmin" or MONGO_ADMIN (if set)
-  pass: "" # defaults to "mongopass" or MONGO_PASS (if set)
-  host: "" # defaults to 127.0.0.1 or MONGO_HOST (if set)
-  port: "" # defaults to 27017 or MONGO_PORT (if set)
-  opts: '' # defaults to '/?authSource=admin' or MONGO_OPTS (if set)
 wg:
   keyrequired: "" # defaults to "". If set to "yes", a key is required for signing up for the comms network 
   grpcwg: "" # defaults to "on" or SERVER_GRPC_WIREGUARD if set

+ 91 - 92
controllers/authGrpc.go

@@ -1,20 +1,19 @@
 package controller
 
 import (
-	"errors"
 	"context"
-        "golang.org/x/crypto/bcrypt"
-        "time"
-        nodepb "github.com/gravitl/netmaker/grpc"
-        "github.com/gravitl/netmaker/models"
-        "github.com/gravitl/netmaker/functions"
-        "github.com/gravitl/netmaker/mongoconn"
-        "go.mongodb.org/mongo-driver/bson"
+	"encoding/json"
+	"errors"
+
+	"github.com/gravitl/netmaker/database"
+	"github.com/gravitl/netmaker/functions"
+	nodepb "github.com/gravitl/netmaker/grpc"
+	"github.com/gravitl/netmaker/models"
+	"golang.org/x/crypto/bcrypt"
 	"google.golang.org/grpc"
+	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/metadata"
 	"google.golang.org/grpc/status"
-	"google.golang.org/grpc/codes"
-
 )
 
 func AuthServerUnaryInterceptor(ctx context.Context,
@@ -24,15 +23,14 @@ func AuthServerUnaryInterceptor(ctx context.Context,
 	// Skip authorize when GetJWT is requested
 
 	if info.FullMethod != "/node.NodeService/Login" {
-	if info.FullMethod != "/node.NodeService/CreateNode" {
+		if info.FullMethod != "/node.NodeService/CreateNode" {
 
-		err := grpcAuthorize(ctx)
-		if err != nil {
-			return nil, err
+			err := grpcAuthorize(ctx)
+			if err != nil {
+				return nil, err
+			}
 		}
 	}
-	}
-
 
 	// Calls the handler
 	h, err := handler(ctx, req)
@@ -40,66 +38,65 @@ func AuthServerUnaryInterceptor(ctx context.Context,
 	return h, err
 }
 func AuthServerStreamInterceptor(
-		srv interface{},
-		stream grpc.ServerStream,
-		info *grpc.StreamServerInfo,
-		handler grpc.StreamHandler,
-	) error {
-		if info.FullMethod == "/node.NodeService/GetPeers" {
-			if err := grpcAuthorize(stream.Context()); err != nil {
-				return err
-			}
+	srv interface{},
+	stream grpc.ServerStream,
+	info *grpc.StreamServerInfo,
+	handler grpc.StreamHandler,
+) error {
+	if info.FullMethod == "/node.NodeService/GetPeers" {
+		if err := grpcAuthorize(stream.Context()); err != nil {
+			return err
 		}
+	}
 
-
-		// Calls the handler
-		return handler(srv, stream)
+	// Calls the handler
+	return handler(srv, stream)
 }
 
 func grpcAuthorize(ctx context.Context) error {
 
+	md, ok := metadata.FromIncomingContext(ctx)
 
-		md, ok := metadata.FromIncomingContext(ctx)
-
-		if !ok {
-			return status.Errorf(codes.InvalidArgument, "Retrieving metadata is failed")
-		}
+	if !ok {
+		return status.Errorf(codes.InvalidArgument, "Retrieving metadata is failed")
+	}
 
-		authHeader, ok := md["authorization"]
-		if !ok {
-			return status.Errorf(codes.Unauthenticated, "Authorization token is not supplied")
-		}
+	authHeader, ok := md["authorization"]
+	if !ok {
+		return status.Errorf(codes.Unauthenticated, "Authorization token is not supplied")
+	}
 
-		authToken := authHeader[0]
+	authToken := authHeader[0]
 
-		mac, network, err := functions.VerifyToken(authToken)
+	mac, network, err := functions.VerifyToken(authToken)
 
-		if err  != nil { return err }
+	if err != nil {
+		return err
+	}
 
-                networkexists, err := functions.NetworkExists(network)
+	networkexists, err := functions.NetworkExists(network)
 
-		if err != nil {
-			return status.Errorf(codes.Unauthenticated, "Unauthorized. Network does not exist: " + network)
+	if err != nil {
+		return status.Errorf(codes.Unauthenticated, "Unauthorized. Network does not exist: "+network)
 
-		}
-		emptynode := models.Node{}
-		node, err := functions.GetNodeByMacAddress(network, mac)
-		if err != nil || node.MacAddress == emptynode.MacAddress {
-                        return status.Errorf(codes.Unauthenticated, "Node does not exist.")
-		}
+	}
+	emptynode := models.Node{}
+	node, err := functions.GetNodeByMacAddress(network, mac)
+	if err != nil || node.MacAddress == emptynode.MacAddress {
+		return status.Errorf(codes.Unauthenticated, "Node does not exist.")
+	}
 
-                //check that the request is for a valid network
-                //if (networkCheck && !networkexists) || err != nil {
-                if (!networkexists) {
+	//check that the request is for a valid network
+	//if (networkCheck && !networkexists) || err != nil {
+	if !networkexists {
 
-			return status.Errorf(codes.Unauthenticated, "Network does not exist.")
+		return status.Errorf(codes.Unauthenticated, "Network does not exist.")
 
-                } else {
-                        return nil
-                }
+	} else {
+		return nil
+	}
 }
 
-
 //Node authenticates using its password and retrieves a JWT for authorization.
 func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.LoginRequest) (*nodepb.LoginResponse, error) {
 
@@ -112,48 +109,50 @@ func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.LoginRequest)
 
 	err := errors.New("Generic server error.")
 
-
-        if macaddress == "" {
+	if macaddress == "" {
 		//TODO: Set Error  response
 		err = errors.New("Missing Mac Address.")
 		return nil, err
-        } else if password == "" {
-                err = errors.New("Missing Password.")
-                return nil, err
-        } else {
-            //Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API untill approved).
-            collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-            ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	    var err = collection.FindOne(ctx, bson.M{ "macaddress": macaddress, "network": network}).Decode(&result)
-
-            defer cancel()
-
-            if err != nil {
-                return nil, err
-            }
-
-           //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...
-           //TODO: Consider a way of hashing the password client side before sending, or using certificates
-           err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(password))
-	   if err != nil && result.Password != password {
-			return nil, err
-           } else {
-                //Create a new JWT for the node
-                tokenString, err := functions.CreateJWT(macaddress, result.Network)
-
+	} else if password == "" {
+		err = errors.New("Missing Password.")
+		return nil, err
+	} else {
+		//Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API untill approved).
+		collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
 		if err != nil {
 			return nil, err
 		}
-                if tokenString == "" {
-		    err = errors.New("Something went wrong. Could not retrieve token.")
-                    return nil, err
-                }
+		for _, value := range collection {
+			if err = json.Unmarshal([]byte(value), &result); err != nil {
+				continue // finish going through nodes
+			}
+			if result.MacAddress == macaddress && result.Network == network {
+				break
+			}
+		}
+
+		//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...
+		//TODO: Consider a way of hashing the password client side before sending, or using certificates
+		err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(password))
+		if err != nil && result.Password != password {
+			return nil, err
+		} else {
+			//Create a new JWT for the node
+			tokenString, err := functions.CreateJWT(macaddress, result.Network)
 
-		response := &nodepb.LoginResponse{
+			if err != nil {
+				return nil, err
+			}
+			if tokenString == "" {
+				err = errors.New("Something went wrong. Could not retrieve token.")
+				return nil, err
+			}
+
+			response := &nodepb.LoginResponse{
 				Accesstoken: tokenString,
 			}
-		return response, nil
-        }
-    }
+			return response, nil
+		}
+	}
 }

+ 99 - 187
controllers/common.go

@@ -1,61 +1,41 @@
 package controller
 
 import (
-	"context"
 	"encoding/json"
 	"fmt"
-	"log"
 	"time"
 
 	"github.com/go-playground/validator/v10"
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/functions"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
 	"github.com/gravitl/netmaker/servercfg"
-	"github.com/gravitl/netmaker/serverctl"
-	"go.mongodb.org/mongo-driver/bson"
-	"go.mongodb.org/mongo-driver/mongo/options"
 	"golang.org/x/crypto/bcrypt"
 )
 
 func GetPeersList(networkName string) ([]models.PeersResponse, error) {
 
 	var peers []models.PeersResponse
-
-	//Connection mongoDB with mongoconn class
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	//Get all nodes in the relevant network which are NOT in pending state
-	filter := bson.M{"network": networkName, "ispending": false}
-	cur, err := collection.Find(ctx, filter)
+	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
 
 	if err != nil {
 		return peers, err
 	}
 
-	// Close the cursor once finished and cancel if it takes too long
-	defer cancel()
-
-	for cur.Next(context.TODO()) {
-
+	for _, value := range collection {
+		var node models.Node
 		var peer models.PeersResponse
-		err := cur.Decode(&peer)
+		err := json.Unmarshal([]byte(value), &node)
 		if err != nil {
-			log.Fatal(err)
+			continue
+		}
+		err = json.Unmarshal([]byte(value), &peer)
+		if err != nil {
+			continue
+		}
+		if node.Network == networkName && !node.IsPending {
+			peers = append(peers, peer)
 		}
-
-		// add the node to our node array
-		//maybe better to just return this? But then that's just GetNodes...
-		peers = append(peers, peer)
-	}
-
-	//Uh oh, fatal error! This needs some better error handling
-	//TODO: needs appropriate error handling so the server doesnt shut down.
-	if err := cur.Err(); err != nil {
-		log.Fatal(err)
 	}
 
 	return peers, err
@@ -72,12 +52,16 @@ func GetExtPeersList(networkName string, macaddress string) ([]models.ExtPeersRe
 
 	for _, value := range records {
 		var peer models.ExtPeersResponse
+		var extClient models.ExtClient
 		err = json.Unmarshal([]byte(value), &peer)
+		err = json.Unmarshal([]byte(value), &extClient)
 		if err != nil {
 			functions.PrintUserLog("netmaker", "failed to unmarshal ext client", 2)
 			continue
 		}
-		peers = append(peers, peer)
+		if extClient.Network == networkName && extClient.IngressGatewayID == macaddress {
+			peers = append(peers, peer)
+		}
 	}
 	return peers, err
 }
@@ -109,7 +93,7 @@ func ValidateNodeCreate(networkName string, node models.Node) error {
 func ValidateNodeUpdate(networkName string, node models.NodeUpdate) error {
 	v := validator.New()
 	_ = v.RegisterValidation("network_exists", func(fl validator.FieldLevel) bool {
-		_, err := node.GetNetwork()
+		_, err := functions.GetParentNetwork(networkName)
 		return err == nil
 	})
 	_ = v.RegisterValidation("in_charset", func(fl validator.FieldLevel) bool {
@@ -128,8 +112,11 @@ func ValidateNodeUpdate(networkName string, node models.NodeUpdate) error {
 func UpdateNode(nodechange models.NodeUpdate, node models.Node) (models.Node, error) {
 	//Question: Is there a better way  of doing  this than a bunch of "if" statements? probably...
 	//Eventually, lets have a better way to check if any of the fields are filled out...
-	queryMac := node.MacAddress
-	queryNetwork := node.Network
+	oldkey, err := functions.GetRecordKey(node.MacAddress, node.Network)
+	if err != nil {
+		return node, err
+	}
+
 	notifynetwork := false
 
 	if nodechange.Address != "" {
@@ -193,129 +180,75 @@ func UpdateNode(nodechange models.NodeUpdate, node models.Node) (models.Node, er
 		node.KeyUpdateTimeStamp = time.Now().Unix()
 		notifynetwork = true
 	}
-
-	//collection := mongoconn.ConnectDB()
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	// Create filter
-	filter := bson.M{"macaddress": queryMac, "network": queryNetwork}
-
-	node.SetLastModified()
-
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"address", node.Address},
-			{"address6", node.Address6},
-			{"name", node.Name},
-			{"password", node.Password},
-			{"listenport", node.ListenPort},
-			{"publickey", node.PublicKey},
-			{"keyupdatetimestamp", node.KeyUpdateTimeStamp},
-			{"expdatetime", node.ExpirationDateTime},
-			{"endpoint", node.Endpoint},
-			{"postup", node.PostUp},
-			{"postdown", node.PostDown},
-			{"macaddress", node.MacAddress},
-			{"localaddress", node.LocalAddress},
-			{"persistentkeepalive", node.PersistentKeepalive},
-			{"saveconfig", node.SaveConfig},
-			{"accesskey", node.AccessKey},
-			{"interface", node.Interface},
-			{"lastmodified", node.LastModified},
-		}},
-	}
-	var nodeupdate models.Node
-	errN := collection.FindOneAndUpdate(ctx, filter, update).Decode(&nodeupdate)
-	if errN != nil {
-		return nodeupdate, errN
+	newkey, err := functions.GetRecordKey(node.MacAddress, node.Network)
+	if err != nil {
+		return node, err
 	}
-
-	if nodechange.MacAddress != "" {
-		queryMac = nodechange.MacAddress
+	if oldkey != newkey {
+		if err := database.DeleteRecord(database.NODES_TABLE_NAME, oldkey); err != nil {
+			return models.Node{}, err
+		}
+	}
+	value, err := json.Marshal(&node)
+	if err != nil {
+		return models.Node{}, err
 	}
-	returnnode, errN := GetNode(queryMac, queryNetwork)
 
-	defer cancel()
+	err = database.Insert(newkey, string(value), database.NODES_TABLE_NAME)
 
 	if notifynetwork {
-		errN = SetNetworkNodesLastModified(queryNetwork)
+		err = SetNetworkNodesLastModified(node.Network)
 	}
 	if servercfg.IsDNSMode() {
-		errN = SetDNS()
+		err = SetDNS()
 	}
 
-	return returnnode, errN
+	return node, err
 }
 
-func DeleteNode(macaddress string, network string) (bool, error) {
-
-	deleted := false
-
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
+func DeleteNode(macaddress string, network string) error {
 
-	filter := bson.M{"macaddress": macaddress, "network": network}
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	result, err := collection.DeleteOne(ctx, filter)
-
-	deletecount := result.DeletedCount
-
-	if deletecount > 0 {
-		deleted = true
+	key, err := functions.GetRecordKey(macaddress, network)
+	if err != nil {
+		return err
+	}
+	if err = database.DeleteRecord(database.NODES_TABLE_NAME, key); err != nil {
+		return err
 	}
-
-	defer cancel()
 
 	err = SetNetworkNodesLastModified(network)
-	fmt.Println("Deleted node " + macaddress + " from network " + network)
 	if servercfg.IsDNSMode() {
 		err = SetDNS()
 	}
 
-	return deleted, err
+	return err
 }
 
 func DeleteIntClient(clientid string) (bool, error) {
 
-	deleted := false
-
-	collection := mongoconn.Client.Database("netmaker").Collection("intclients")
-
-	filter := bson.M{"clientid": clientid}
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	result, err := collection.DeleteOne(ctx, filter)
-
-	deletecount := result.DeletedCount
-
-	if deletecount > 0 {
-		deleted = true
+	err := database.DeleteRecord(database.INT_CLIENTS_TABLE_NAME, clientid)
+	if err != nil {
+		return false, err
 	}
 
-	defer cancel()
-
-	err = serverctl.ReconfigureServerWireGuard()
-
-	return deleted, err
+	return true, nil
 }
 
 func GetNode(macaddress string, network string) (models.Node, error) {
 
 	var node models.Node
 
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	filter := bson.M{"macaddress": macaddress, "network": network}
-	err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&node)
-
-	defer cancel()
+	key, err := functions.GetRecordKey(macaddress, network)
+	if err != nil {
+		return node, err
+	}
+	data, err := database.FetchRecord(database.NODES_TABLE_NAME, key)
+	if err != nil {
+		return node, err
+	}
+	if err = json.Unmarshal([]byte(data), &node); err != nil {
+		return node, err
+	}
 
 	return node, err
 }
@@ -324,16 +257,14 @@ func GetIntClient(clientid string) (models.IntClient, error) {
 
 	var client models.IntClient
 
-	collection := mongoconn.Client.Database("netmaker").Collection("intclients")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	filter := bson.M{"clientid": clientid}
-	err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&clientid)
-
-	defer cancel()
-
-	return client, err
+	value, err := database.FetchRecord(database.INT_CLIENTS_TABLE_NAME, clientid)
+	if err != nil {
+		return client, err
+	}
+	if err = json.Unmarshal([]byte(value), &client); err != nil {
+		return models.IntClient{}, err
+	}
+	return client, nil
 }
 
 func CreateNode(node models.Node, networkName string) (models.Node, error) {
@@ -384,17 +315,16 @@ func CreateNode(node models.Node, networkName string) (models.Node, error) {
 		//returnErrorResponse(w, r, errorResponse)
 		return node, err
 	}
+	key, err := functions.GetRecordKey(node.MacAddress, node.Network)
+	if err != nil {
+		return node, err
+	}
+	nodebytes, err := json.Marshal(&node)
+	if err != nil {
+		return node, err
+	}
 
-	// connect db
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	// insert our node to the node db.
-	result, err := collection.InsertOne(ctx, node)
-	_ = result
-
-	defer cancel()
-
+	err = database.Insert(key, string(nodebytes), database.NODES_TABLE_NAME)
 	if err != nil {
 		return node, err
 	}
@@ -422,7 +352,7 @@ func NodeCheckIn(node models.Node, networkName string) (models.CheckInResponse,
 		return response, err
 	}
 
-	parentnode, err := functions.GetNodeByMacAddress(networkName, node.MacAddress)
+	parentnode, err := GetNode(node.MacAddress, networkName)
 	if err != nil {
 		err = fmt.Errorf("%w; Couldnt Get Node "+node.MacAddress, err)
 		return response, err
@@ -456,7 +386,7 @@ func NodeCheckIn(node models.Node, networkName string) (models.CheckInResponse,
 	}
 	if time.Now().Unix() > parentnode.ExpirationDateTime {
 		response.NeedDelete = true
-		_, err = DeleteNode(node.MacAddress, networkName)
+		err = DeleteNode(node.MacAddress, networkName)
 	} else {
 		err = TimestampNode(parentnode, true, false, false)
 
@@ -474,28 +404,19 @@ func SetNetworkNodesLastModified(networkName string) error {
 
 	timestamp := time.Now().Unix()
 
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	// Create filter
-	filter := bson.M{"netid": networkName}
-
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"nodeslastmodified", timestamp},
-		}},
+	network, err := functions.GetParentNetwork(networkName)
+	if err != nil {
+		return err
 	}
-
-	result := collection.FindOneAndUpdate(ctx, filter, update)
-
-	defer cancel()
-
-	if result.Err() != nil {
-		return result.Err()
+	network.NodesLastModified = timestamp
+	data, err := json.Marshal(&network)
+	if err != nil {
+		return err
+	}
+	err = database.Insert(networkName, string(data), database.NETWORKS_TABLE_NAME)
+	if err != nil {
+		return err
 	}
-
 	return nil
 }
 
@@ -510,25 +431,16 @@ func TimestampNode(node models.Node, updatecheckin bool, updatepeers bool, updat
 		node.SetLastPeerUpdate()
 	}
 
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	// Create filter
-	filter := bson.M{"macaddress": node.MacAddress, "network": node.Network}
-
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"lastmodified", node.LastModified},
-			{"lastpeerupdate", node.LastPeerUpdate},
-			{"lastcheckin", node.LastCheckIn},
-		}},
+	key, err := functions.GetRecordKey(node.MacAddress, node.Network)
+	if err != nil {
+		return err
+	}
+	value, err := json.Marshal(&node)
+	if err != nil {
+		return err
 	}
 
-	var nodeupdate models.Node
-	err := collection.FindOneAndUpdate(ctx, filter, update).Decode(&nodeupdate)
-	defer cancel()
+	err = database.Insert(key, string(value), database.NODES_TABLE_NAME)
 
 	return err
 }

+ 11 - 19
controllers/common_test.go

@@ -1,14 +1,13 @@
 package controller
 
 import (
-	"context"
+	"encoding/json"
 	"testing"
 	"time"
 
+	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
 	"github.com/stretchr/testify/assert"
-	"go.mongodb.org/mongo-driver/bson"
 )
 
 type NodeValidationTC struct {
@@ -51,14 +50,12 @@ func TestDeleteNode(t *testing.T) {
 	createNet()
 	node := createTestNode(t)
 	t.Run("NodeExists", func(t *testing.T) {
-		deleted, err := DeleteNode(node.MacAddress, node.Network)
+		err := DeleteNode(node.MacAddress, node.Network)
 		assert.Nil(t, err)
-		assert.True(t, deleted)
 	})
 	t.Run("NonExistantNode", func(t *testing.T) {
-		deleted, err := DeleteNode(node.MacAddress, node.Network)
+		err := DeleteNode(node.MacAddress, node.Network)
 		assert.Nil(t, err)
-		assert.False(t, deleted)
 	})
 }
 func TestGetNode(t *testing.T) {
@@ -89,7 +86,7 @@ func TestGetNode(t *testing.T) {
 		assert.Equal(t, "mongo: no documents in result", err.Error())
 	})
 	t.Run("NoNode", func(t *testing.T) {
-		_, _ = DeleteNode("01:02:03:04:05:06", "skynet")
+		_ = DeleteNode("01:02:03:04:05:06", "skynet")
 		response, err := GetNode(node.MacAddress, node.Network)
 		assert.NotNil(t, err)
 		assert.Equal(t, models.Node{}, response)
@@ -110,7 +107,7 @@ func TestGetPeerList(t *testing.T) {
 		t.Log(peers)
 	})
 	t.Run("NoNodes", func(t *testing.T) {
-		_, _ = DeleteNode("01:02:03:04:05:06", "skynet")
+		_ = DeleteNode("01:02:03:04:05:06", "skynet")
 		peers, err := GetPeersList("skynet")
 		assert.Nil(t, err)
 		assert.Equal(t, []models.PeersResponse(nil), peers)
@@ -178,17 +175,12 @@ func TestNodeCheckIn(t *testing.T) {
 		newtime := time.Now().Add(time.Hour * 24).Unix()
 		t.Log(newtime, time.Now().Unix())
 		//this is cheating; but can't find away to update timestamp through existing api
-		collection := mongoconn.Client.Database("netmaker").Collection("networks")
-		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-		filter := bson.M{"netid": "skynet"}
-		update := bson.D{
-			{"$set", bson.D{
-				{"keyupdatetimestamp", newtime},
-			}},
-		}
-		defer cancel()
-		err := collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
+
+		record, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, "skynet")
+		assert.Nil(t, err)
+		err = json.Unmarshal([]byte(record), &network)
 		assert.Nil(t, err)
+		network.KeyUpdateTimeStamp = newtime
 		response, err := NodeCheckIn(node, "skynet")
 		assert.Nil(t, err)
 		assert.Equal(t, true, response.Success)

+ 41 - 43
controllers/controller.go

@@ -1,63 +1,61 @@
 package controller
 
 import (
-    "github.com/gravitl/netmaker/mongoconn"
-    "github.com/gravitl/netmaker/servercfg"
-    "os/signal"
-    "os"
-    "log"
-    "context"
-    "net/http"
-    "github.com/gorilla/mux"
-    "github.com/gorilla/handlers"
-    "sync"
+	"context"
+	"log"
+	"net/http"
+	"os"
+	"os/signal"
+	"sync"
+
+	"github.com/gorilla/handlers"
+	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/servercfg"
 )
 
-
 func HandleRESTRequests(wg *sync.WaitGroup) {
-    defer wg.Done()
+	defer wg.Done()
 
-    r := mux.NewRouter()
+	r := mux.NewRouter()
 
-    // Currently allowed dev origin is all. Should change in prod
-    // should consider analyzing the allowed methods further
-    headersOk := handlers.AllowedHeaders([]string{"Access-Control-Allow-Origin", "X-Requested-With", "Content-Type", "authorization"})
-    originsOk := handlers.AllowedOrigins([]string{servercfg.GetAllowedOrigin()})
-    methodsOk := handlers.AllowedMethods([]string{"GET", "PUT", "POST", "DELETE"})
+	// Currently allowed dev origin is all. Should change in prod
+	// should consider analyzing the allowed methods further
+	headersOk := handlers.AllowedHeaders([]string{"Access-Control-Allow-Origin", "X-Requested-With", "Content-Type", "authorization"})
+	originsOk := handlers.AllowedOrigins([]string{servercfg.GetAllowedOrigin()})
+	methodsOk := handlers.AllowedMethods([]string{"GET", "PUT", "POST", "DELETE"})
 
-    nodeHandlers(r)
-    userHandlers(r)
-    networkHandlers(r)
-    dnsHandlers(r)
-    fileHandlers(r)
-    serverHandlers(r)
-    extClientHandlers(r)
-    intClientHandlers(r)
+	nodeHandlers(r)
+	userHandlers(r)
+	networkHandlers(r)
+	dnsHandlers(r)
+	fileHandlers(r)
+	serverHandlers(r)
+	extClientHandlers(r)
+	intClientHandlers(r)
 
-		port := servercfg.GetAPIPort()
+	port := servercfg.GetAPIPort()
 
-		srv := &http.Server{Addr: ":" + port, Handler: handlers.CORS(originsOk, headersOk, methodsOk)(r)}
-		go func(){
+	srv := &http.Server{Addr: ":" + port, Handler: handlers.CORS(originsOk, headersOk, methodsOk)(r)}
+	go func() {
 		err := srv.ListenAndServe()
 		if err != nil {
 			log.Println(err)
 		}
-		}()
+	}()
 
-		log.Println("REST Server succesfully started on port " + port + " (REST)")
-		c := make(chan os.Signal)
+	log.Println("REST Server succesfully started on port " + port + " (REST)")
+	c := make(chan os.Signal)
 
-		// Relay os.Interrupt to our channel (os.Interrupt = CTRL+C)
-		// Ignore other incoming signals
-		signal.Notify(c, os.Interrupt)
+	// Relay os.Interrupt to our channel (os.Interrupt = CTRL+C)
+	// Ignore other incoming signals
+	signal.Notify(c, os.Interrupt)
 
-		// Block main routine until a signal is received
-		// As long as user doesn't press CTRL+C a message is not passed and our main routine keeps running
-		<-c
+	// Block main routine until a signal is received
+	// As long as user doesn't press CTRL+C a message is not passed and our main routine keeps running
+	<-c
 
-		// After receiving CTRL+C Properly stop the server
-		log.Println("Stopping the REST server...")
-		srv.Shutdown(context.TODO())
-                log.Println("REST Server closed.")
-		mongoconn.Client.Disconnect(context.TODO())
+	// After receiving CTRL+C Properly stop the server
+	log.Println("Stopping the REST server...")
+	srv.Shutdown(context.TODO())
+	log.Println("REST Server closed.")
 }

+ 56 - 124
controllers/dnsHttpController.go

@@ -1,21 +1,16 @@
 package controller
 
 import (
-	"context"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"net/http"
-	"time"
 
 	"github.com/go-playground/validator/v10"
 	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/functions"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
 	"github.com/txn2/txeh"
-	"go.mongodb.org/mongo-driver/bson"
-	"go.mongodb.org/mongo-driver/mongo/options"
 )
 
 func dnsHandlers(r *mux.Router) {
@@ -82,39 +77,23 @@ func GetNodeDNS(network string) ([]models.DNSEntry, error) {
 
 	var dns []models.DNSEntry
 
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	filter := bson.M{"network": network}
-
-	cur, err := collection.Find(ctx, filter, options.Find().SetProjection(bson.M{"_id": 0}))
-
+	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
 	if err != nil {
 		return dns, err
 	}
 
-	defer cancel()
-
-	for cur.Next(context.TODO()) {
-
+	for _, value := range collection {
 		var entry models.DNSEntry
-
-		err := cur.Decode(&entry)
-		if err != nil {
-			return dns, err
+		var node models.Node
+		if err = json.Unmarshal([]byte(value), &node); err != nil {
+			continue
+		}
+		if err = json.Unmarshal([]byte(value), &entry); node.Network == network && err == nil {
+			dns = append(dns, entry)
 		}
-
-		// add item our array of nodes
-		dns = append(dns, entry)
-	}
-
-	//TODO: Another fatal error we should take care of.
-	if err := cur.Err(); err != nil {
-		return dns, err
 	}
 
-	return dns, err
+	return dns, nil
 }
 
 //Gets all nodes associated with network, including pending nodes
@@ -140,36 +119,20 @@ func GetCustomDNS(network string) ([]models.DNSEntry, error) {
 
 	var dns []models.DNSEntry
 
-	collection := mongoconn.Client.Database("netmaker").Collection("dns")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	filter := bson.M{"network": network}
-
-	cur, err := collection.Find(ctx, filter, options.Find().SetProjection(bson.M{"_id": 0}))
-
+	collection, err := database.FetchRecords(database.DNS_TABLE_NAME)
 	if err != nil {
 		return dns, err
 	}
-
-	defer cancel()
-
-	for cur.Next(context.TODO()) {
-
+	for _, value := range collection { // filter for entries based on network
 		var entry models.DNSEntry
 
-		err := cur.Decode(&entry)
-		if err != nil {
-			return dns, err
+		if err := json.Unmarshal([]byte(value), entry); err != nil {
+			continue
 		}
 
-		// add item our array of nodes
-		dns = append(dns, entry)
-	}
-
-	//TODO: Another fatal error we should take care of.
-	if err := cur.Err(); err != nil {
-		return dns, err
+		if entry.Network == network {
+			dns = append(dns, entry)
+		}
 	}
 
 	return dns, err
@@ -343,109 +306,78 @@ func deleteDNS(w http.ResponseWriter, r *http.Request) {
 	// get params
 	var params = mux.Vars(r)
 
-	success, err := DeleteDNS(params["domain"], params["network"])
+	err := DeleteDNS(params["domain"], params["network"])
 
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
-	} else if !success {
-		returnErrorResponse(w, r, formatError(errors.New("Delete unsuccessful."), "badrequest"))
-		return
 	}
-
-	json.NewEncoder(w).Encode(params["domain"] + " deleted.")
+	entrytext := params["domain"] + "." + params["network"]
+	functions.PrintUserLog("netmaker", "deleted dns entry: "+entrytext, 1)
+	json.NewEncoder(w).Encode(entrytext + " deleted.")
 }
 
 func CreateDNS(entry models.DNSEntry) (models.DNSEntry, error) {
 
-	// connect db
-	collection := mongoconn.Client.Database("netmaker").Collection("dns")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	// insert our node to the node db.
-	_, err := collection.InsertOne(ctx, entry)
-
-	defer cancel()
+	data, err := json.Marshal(&entry)
+	if err != nil {
+		return models.DNSEntry{}, err
+	}
+	key, err := functions.GetRecordKey(entry.Name, entry.Network)
+	if err != nil {
+		return models.DNSEntry{}, err
+	}
+	err = database.Insert(key, string(data), database.DNS_TABLE_NAME)
 
 	return entry, err
 }
 
 func GetDNSEntry(domain string, network string) (models.DNSEntry, error) {
 	var entry models.DNSEntry
-
-	collection := mongoconn.Client.Database("netmaker").Collection("dns")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	filter := bson.M{"name": domain, "network": network}
-	err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&entry)
-
-	defer cancel()
-
+	key, err := functions.GetRecordKey(domain, network)
+	if err != nil {
+		return entry, err
+	}
+	record, err := database.FetchRecord(database.DNS_TABLE_NAME, key)
+	if err != nil {
+		return entry, err
+	}
+	err = json.Unmarshal([]byte(record), &entry)
 	return entry, err
 }
 
 func UpdateDNS(dnschange models.DNSEntry, entry models.DNSEntry) (models.DNSEntry, error) {
 
-	queryDNS := entry.Name
-
+	key, err := functions.GetRecordKey(entry.Name, entry.Network)
+	if err != nil {
+		return entry, err
+	}
 	if dnschange.Name != "" {
 		entry.Name = dnschange.Name
 	}
 	if dnschange.Address != "" {
 		entry.Address = dnschange.Address
 	}
-	//collection := mongoconn.ConnectDB()
-	collection := mongoconn.Client.Database("netmaker").Collection("dns")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	// Create filter
-	filter := bson.M{"name": queryDNS}
-
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"name", entry.Name},
-			{"address", entry.Address},
-		}},
-	}
-	var dnsupdate models.DNSEntry
+	newkey, err := functions.GetRecordKey(entry.Name, entry.Network)
 
-	errN := collection.FindOneAndUpdate(ctx, filter, update).Decode(&dnsupdate)
-	if errN != nil {
-		fmt.Println("Could not update: ")
-		fmt.Println(errN)
-	} else {
-		fmt.Println("DNS Entry updated successfully.")
+	err = database.DeleteRecord(database.DNS_TABLE_NAME, key)
+	if err != nil {
+		return entry, err
 	}
 
-	defer cancel()
+	data, err := json.Marshal(&entry)
+	err = database.Insert(newkey, string(data), database.DNS_TABLE_NAME)
+	return entry, err
 
-	return dnsupdate, errN
 }
 
-func DeleteDNS(domain string, network string) (bool, error) {
-	fmt.Println("delete dns entry ", domain, network)
-	deleted := false
-
-	collection := mongoconn.Client.Database("netmaker").Collection("dns")
-
-	filter := bson.M{"name": domain, "network": network}
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	result, err := collection.DeleteOne(ctx, filter)
-
-	deletecount := result.DeletedCount
-
-	if deletecount > 0 {
-		deleted = true
+func DeleteDNS(domain string, network string) error {
+	key, err := functions.GetRecordKey(domain, network)
+	if err != nil {
+		return err
 	}
-
-	defer cancel()
-
-	return deleted, err
+	err = database.DeleteRecord(database.DNS_TABLE_NAME, key)
+	return err
 }
 
 func pushDNS(w http.ResponseWriter, r *http.Request) {

+ 4 - 6
controllers/dnsHttpController_test.go

@@ -54,21 +54,19 @@ func TestUpdateDNS(t *testing.T) {
 }
 func TestDeleteDNS(t *testing.T) {
 	t.Run("EntryExists", func(t *testing.T) {
-		success, err := DeleteDNS("myhost", "skynet")
+		err := DeleteDNS("myhost", "skynet")
 		assert.Nil(t, err)
-		assert.True(t, success)
 	})
 	t.Run("NoEntry", func(t *testing.T) {
-		success, err := DeleteDNS("myhost", "skynet")
+		err := DeleteDNS("myhost", "skynet")
 		assert.Nil(t, err)
-		assert.False(t, success)
 	})
 
 }
 
 func TestValidateDNSUpdate(t *testing.T) {
 	entry := models.DNSEntry{"10.0.0.2", "myhost", "skynet"}
-	_, _ = DeleteDNS("mynode", "skynet")
+	_ = DeleteDNS("mynode", "skynet")
 	t.Run("BadNetwork", func(t *testing.T) {
 		change := models.DNSEntry{"10.0.0.2", "myhost", "badnet"}
 		err := ValidateDNSUpdate(change, entry)
@@ -129,7 +127,7 @@ func TestValidateDNSUpdate(t *testing.T) {
 
 }
 func TestValidateDNSCreate(t *testing.T) {
-	_, _ = DeleteDNS("mynode", "skynet")
+	_ = DeleteDNS("mynode", "skynet")
 	t.Run("NoNetwork", func(t *testing.T) {
 		entry := models.DNSEntry{"10.0.0.2", "myhost", "badnet"}
 		err := ValidateDNSCreate(entry)

+ 119 - 155
controllers/extClientHttpController.go

@@ -1,25 +1,23 @@
 package controller
 
 import (
-	"context"
 	"encoding/json"
-	"io"
 	"errors"
 	"fmt"
-        "math/rand"
+	"io"
+	"math/rand"
 
 	// "fmt"
 	"net/http"
-	"time"
 	"strconv"
+	"time"
+
 	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/functions"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
-	"go.mongodb.org/mongo-driver/bson"
-	"go.mongodb.org/mongo-driver/mongo/options"
-	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 	"github.com/skip2/go-qrcode"
+	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 
 func extClientHandlers(r *mux.Router) {
@@ -98,34 +96,22 @@ func getNetworkExtClients(w http.ResponseWriter, r *http.Request) {
 
 func GetNetworkExtClients(network string) ([]models.ExtClient, error) {
 	var extclients []models.ExtClient
-	collection := mongoconn.Client.Database("netmaker").Collection("extclients")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"network": network}
-	//Filtering out the ID field cuz Dillon doesn't like it. May want to filter out other fields in the future
-	cur, err := collection.Find(ctx, filter, options.Find().SetProjection(bson.M{"_id": 0}))
+
+	records, err := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME)
 	if err != nil {
-		return []models.ExtClient{}, err
-	}
-	defer cancel()
-	for cur.Next(context.TODO()) {
-		//Using a different model for the ReturnExtClient (other than regular extclient).
-		//Either we should do this for ALL structs (so Networks and Keys)
-		//OR we should just use the original struct
-		//My preference is to make some new return structs
-		//TODO: Think about this. Not an immediate concern. Just need to get some consistency eventually
+		return extclients, err
+	}
+	for _, value := range records {
 		var extclient models.ExtClient
-		err := cur.Decode(&extclient)
+		err = json.Unmarshal([]byte(value), &extclient)
 		if err != nil {
-			return []models.ExtClient{}, err
+			continue
+		}
+		if extclient.Network == network {
+			extclients = append(extclients, extclient)
 		}
-		// add item our array of extclients
-		extclients = append(extclients, extclient)
-	}
-	//TODO: Another fatal error we should take care of.
-	if err := cur.Err(); err != nil {
-		return []models.ExtClient{}, err
 	}
-	return extclients, nil
+	return extclients, err
 }
 
 //A separate function to get all extclients, not just extclients for a particular network.
@@ -149,58 +135,60 @@ func getExtClient(w http.ResponseWriter, r *http.Request) {
 
 	var params = mux.Vars(r)
 
-	var extclient models.ExtClient
-
-	collection := mongoconn.Client.Database("netmaker").Collection("extclients")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	filter := bson.M{"network": params["network"], "clientid": params["clientid"]}
-	err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&extclient)
+	clientid := params["clientid"]
+	network := params["network"]
+	client, err := GetExtClient(clientid, network)
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 	}
 
-	defer cancel()
-
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(extclient)
+	json.NewEncoder(w).Encode(client)
 }
 
-//Get an individual extclient. Nothin fancy here folks.
-func getExtClientConf(w http.ResponseWriter, r *http.Request) {
-        // set header.
-        w.Header().Set("Content-Type", "application/json")
-
-        var params = mux.Vars(r)
+func GetExtClient(clientid string, network string) (models.ExtClient, error) {
+	var extclient models.ExtClient
+	key, err := functions.GetRecordKey(clientid, network)
+	if err != nil {
+		return extclient, err
+	}
+	data, err := database.FetchRecord(database.EXT_CLIENT_TABLE_NAME, key)
+	if err != nil {
+		return extclient, err
+	}
+	err = json.Unmarshal([]byte(data), &extclient)
 
-        var extclient models.ExtClient
+	return extclient, err
+}
 
-        collection := mongoconn.Client.Database("netmaker").Collection("extclients")
+//Get an individual extclient. Nothin fancy here folks.
+func getExtClientConf(w http.ResponseWriter, r *http.Request) {
+	// set header.
+	w.Header().Set("Content-Type", "application/json")
 
-        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	var params = mux.Vars(r)
+	clientid := params["clientid"]
+	networkid := params["network"]
+	client, err := GetExtClient(clientid, networkid)
+	if err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
 
-        filter := bson.M{"network": params["network"], "clientid": params["clientid"]}
-        err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&extclient)
-        if err != nil {
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
+	gwnode, err := functions.GetNodeByMacAddress(client.Network, client.IngressGatewayID)
+	if err != nil {
+		fmt.Println("Could not retrieve Ingress Gateway Node " + client.IngressGatewayID)
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
 
-        gwnode, err := functions.GetNodeByMacAddress(extclient.Network, extclient.IngressGatewayID)
-        if err != nil {
-		fmt.Println("Could not retrieve Ingress Gateway Node " + extclient.IngressGatewayID)
+	network, err := functions.GetParentNetwork(client.Network)
+	if err != nil {
+		fmt.Println("Could not retrieve Ingress Gateway Network " + client.Network)
 		returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
-
-	network, err := functions.GetParentNetwork(extclient.Network)
-        if err != nil {
-                fmt.Println("Could not retrieve Ingress Gateway Network " + extclient.Network)
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
+		return
+	}
 	keepalive := ""
 	if network.DefaultKeepalive != 0 {
 		keepalive = "PersistentKeepalive = " + strconv.Itoa(int(network.DefaultKeepalive))
@@ -216,12 +204,12 @@ AllowedIPs = %s
 Endpoint = %s
 %s
 
-`, extclient.Address + "/32",
-   extclient.PrivateKey,
-   gwnode.PublicKey,
-   network.AddressRange,
-   gwendpoint,
-   keepalive)
+`, client.Address+"/32",
+		client.PrivateKey,
+		gwnode.PublicKey,
+		network.AddressRange,
+		gwendpoint,
+		keepalive)
 
 	if params["type"] == "qr" {
 		bytes, err := qrcode.Encode(config, qrcode.Medium, 220)
@@ -240,21 +228,19 @@ Endpoint = %s
 	}
 
 	if params["type"] == "file" {
-		name := extclient.ClientID + ".conf"
-                w.Header().Set("Content-Type", "application/config")
-		w.Header().Set("Content-Disposition", "attachment; filename=\"" + name + "\"")
+		name := client.ClientID + ".conf"
+		w.Header().Set("Content-Type", "application/config")
+		w.Header().Set("Content-Disposition", "attachment; filename=\""+name+"\"")
 		w.WriteHeader(http.StatusOK)
 		_, err := fmt.Fprint(w, config)
 		if err != nil {
-                        returnErrorResponse(w, r, formatError(err, "internal"))
+			returnErrorResponse(w, r, formatError(err, "internal"))
 		}
 		return
 	}
 
-        defer cancel()
-
-        w.WriteHeader(http.StatusOK)
-        json.NewEncoder(w).Encode(extclient)
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(client)
 }
 
 func CreateExtClient(extclient models.ExtClient) error {
@@ -276,25 +262,26 @@ func CreateExtClient(extclient models.ExtClient) error {
 		extclient.Address = newAddress
 	}
 
-        if extclient.ClientID == "" {
-                clientid := StringWithCharset(7, charset)
-                clientname := "client-" + clientid
-                extclient.ClientID = clientname
-        }
+	if extclient.ClientID == "" {
+		clientid := StringWithCharset(7, charset)
+		clientname := "client-" + clientid
+		extclient.ClientID = clientname
+	}
 
 	extclient.LastModified = time.Now().Unix()
 
-	collection := mongoconn.Client.Database("netmaker").Collection("extclients")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	// insert our network into the network table
-	_, err := collection.InsertOne(ctx, extclient)
-	defer cancel()
+	key, err := functions.GetRecordKey(extclient.ClientID, extclient.Network)
 	if err != nil {
 		return err
 	}
-
+	data, err := json.Marshal(&extclient)
+	if err != nil {
+		return err
+	}
+	if err = database.Insert(key, string(data), database.EXT_CLIENT_TABLE_NAME); err != nil {
+		return err
+	}
 	err = SetNetworkNodesLastModified(extclient.Network)
-
 	return err
 }
 
@@ -322,9 +309,9 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
 	extclient.IngressGatewayID = macaddress
 	node, err := functions.GetNodeByMacAddress(networkName, macaddress)
 	if err != nil {
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
 	extclient.IngressGatewayEndpoint = node.Endpoint + ":" + strconv.FormatInt(int64(node.ListenPort), 10)
 
 	err = json.NewDecoder(r.Body).Decode(&extclient)
@@ -361,71 +348,49 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
 	// 	returnErrorResponse(w, r, formatError(err, "badrequest"))
 	// 	return
 	// }
-	collection := mongoconn.Client.Database("netmaker").Collection("extclients")
-	ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"network": params["network"], "clientid": params["clientid"]}
-	err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&oldExtClient)
+	key, err := functions.GetRecordKey(params["clientid"], params["network"])
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 	}
-	newclient, err := UpdateExtClient(newExtClient.ClientID, params["network"], oldExtClient)
+	data, err := database.FetchRecord(database.EXT_CLIENT_TABLE_NAME, key)
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 	}
+	if err = json.Unmarshal([]byte(data), &oldExtClient); err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
 
+	newclient, err := UpdateExtClient(newExtClient.ClientID, params["network"], oldExtClient)
+	if err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	functions.PrintUserLog(r.Header.Get("user"), "updated client "+newExtClient.ClientID, 1)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(newclient)
 }
 
 func UpdateExtClient(newclientid string, network string, client models.ExtClient) (models.ExtClient, error) {
 
-        //collection := mongoconn.ConnectDB()
-        collection := mongoconn.Client.Database("netmaker").Collection("extclients")
-
-        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-        // Create filter
-	filter := bson.M{"clientid": client.ClientID, "network": network}
-
-        // prepare update model.
-        update := bson.D{
-                {"$set", bson.D{
-                        {"clientid", newclientid},
-                }},
-        }
-        var clientupdate models.ExtClient
-
-        err := collection.FindOneAndUpdate(ctx, filter, update).Decode(&clientupdate)
-
-        defer cancel()
-
-        return clientupdate, err
+	err := DeleteExtClient(network, client.ClientID)
+	if err != nil {
+		return client, err
+	}
+	client.ClientID = newclientid
+	CreateExtClient(client)
+	return client, err
 }
 
-func DeleteExtClient(network string, clientid string) (bool, error) {
-
-	deleted := false
-
-	collection := mongoconn.Client.Database("netmaker").Collection("extclients")
-
-	filter := bson.M{"network": network, "clientid": clientid}
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	result, err := collection.DeleteOne(ctx, filter)
-
-	deletecount := result.DeletedCount
-
-	if deletecount > 0 {
-		deleted = true
+func DeleteExtClient(network string, clientid string) error {
+	key, err := functions.GetRecordKey(clientid, network)
+	if err != nil {
+		return err
 	}
-
-	defer cancel()
-
-	fmt.Println("Deleted extclient client " + clientid + " from network " + network)
-	return deleted, err
+	err = database.DeleteRecord(database.EXT_CLIENT_TABLE_NAME, key)
+	return err
 }
 
 //Delete a extclient
@@ -437,28 +402,27 @@ func deleteExtClient(w http.ResponseWriter, r *http.Request) {
 	// get params
 	var params = mux.Vars(r)
 
-	success, err := DeleteExtClient(params["network"], params["clientid"])
+	err := DeleteExtClient(params["network"], params["clientid"])
 
 	if err != nil {
-		returnErrorResponse(w, r, formatError(err, "internal"))
-		return
-	} else if !success {
 		err = errors.New("Could not delete extclient " + params["clientid"])
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 	}
+	functions.PrintUserLog(r.Header.Get("user"),
+		"Deleted extclient client "+params["clientid"]+" from network "+params["network"], 1)
 	returnSuccessResponse(w, r, params["clientid"]+" deleted.")
 }
 
 func StringWithCharset(length int, charset string) string {
-        b := make([]byte, length)
-        for i := range b {
-                b[i] = charset[seededRand.Intn(len(charset))]
-        }
-        return string(b)
+	b := make([]byte, length)
+	for i := range b {
+		b[i] = charset[seededRand.Intn(len(charset))]
+	}
+	return string(b)
 }
 
 const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
 
 var seededRand *rand.Rand = rand.New(
-        rand.NewSource(time.Now().UnixNano()))
+	rand.NewSource(time.Now().UnixNano()))

+ 132 - 134
controllers/intClientHttpController.go

@@ -3,17 +3,17 @@ package controller
 import (
 	//	"fmt"
 	// "github.com/davecgh/go-spew/spew"
-	"errors"
-	"context"
+
 	"encoding/json"
+	"errors"
 	"net/http"
-	"time"
+
 	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/functions"
-	"github.com/gravitl/netmaker/serverctl"
-	"github.com/gravitl/netmaker/servercfg"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
+	"github.com/gravitl/netmaker/servercfg"
+	"github.com/gravitl/netmaker/serverctl"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 )
 
@@ -21,99 +21,98 @@ func intClientHandlers(r *mux.Router) {
 
 	r.HandleFunc("/api/intclient/{clientid}", securityCheck(false, http.HandlerFunc(getIntClient))).Methods("GET")
 	r.HandleFunc("/api/intclients", securityCheck(false, http.HandlerFunc(getAllIntClients))).Methods("GET")
-        r.HandleFunc("/api/intclients/deleteall", securityCheck(false, http.HandlerFunc(deleteAllIntClients))).Methods("DELETE")
-        r.HandleFunc("/api/intclient/{clientid}", securityCheck(false, http.HandlerFunc(updateIntClient))).Methods("PUT")
+	r.HandleFunc("/api/intclients/deleteall", securityCheck(false, http.HandlerFunc(deleteAllIntClients))).Methods("DELETE")
+	r.HandleFunc("/api/intclient/{clientid}", securityCheck(false, http.HandlerFunc(updateIntClient))).Methods("PUT")
 	r.HandleFunc("/api/intclient/register", http.HandlerFunc(registerIntClient)).Methods("POST")
 	r.HandleFunc("/api/intclient/{clientid}", http.HandlerFunc(deleteIntClient)).Methods("DELETE")
 }
 
 func getAllIntClients(w http.ResponseWriter, r *http.Request) {
-        w.Header().Set("Content-Type", "application/json")
-        clients, err := functions.GetAllIntClients()
-        if err != nil {
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
-        //Return all the extclients in JSON format
-        w.WriteHeader(http.StatusOK)
-        json.NewEncoder(w).Encode(clients)
+	w.Header().Set("Content-Type", "application/json")
+	clients, err := functions.GetAllIntClients()
+	if err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	//Return all the extclients in JSON format
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(clients)
 }
 
 func deleteAllIntClients(w http.ResponseWriter, r *http.Request) {
-        w.Header().Set("Content-Type", "application/json")
-        err := functions.DeleteAllIntClients()
-        if err != nil {
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
-        w.WriteHeader(http.StatusOK)
+	w.Header().Set("Content-Type", "application/json")
+	err := functions.DeleteAllIntClients()
+	if err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	w.WriteHeader(http.StatusOK)
 }
 
 func deleteIntClient(w http.ResponseWriter, r *http.Request) {
-        w.Header().Set("Content-Type", "application/json")
-        // get params
-        var params = mux.Vars(r)
-
-        success, err := DeleteIntClient(params["clientid"])
-
-        if err != nil {
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        } else if !success {
-                err = errors.New("Could not delete intclient " + params["clientid"])
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
-        returnSuccessResponse(w, r, params["clientid"]+" deleted.")
-}
+	w.Header().Set("Content-Type", "application/json")
+	// get params
+	var params = mux.Vars(r)
+
+	success, err := DeleteIntClient(params["clientid"])
 
+	if err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	} else if !success {
+		err = errors.New("Could not delete intclient " + params["clientid"])
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	returnSuccessResponse(w, r, params["clientid"]+" deleted.")
+}
 
 func getIntClient(w http.ResponseWriter, r *http.Request) {
-        w.Header().Set("Content-Type", "application/json")
-        var params = mux.Vars(r)
+	w.Header().Set("Content-Type", "application/json")
+	var params = mux.Vars(r)
 
 	client, err := GetIntClient(params["clientid"])
-        if err != nil {
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
-        w.WriteHeader(http.StatusOK)
-        json.NewEncoder(w).Encode(client)
+	if err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(client)
 }
 
 func updateIntClient(w http.ResponseWriter, r *http.Request) {
-        w.Header().Set("Content-Type", "application/json")
-
-        var errorResponse = models.ErrorResponse{
-                Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
-        }
-
-        var clientreq models.IntClient
-
-        //get node from body of request
-        err := json.NewDecoder(r.Body).Decode(&clientreq)
-        if err != nil {
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
-        if servercfg.IsRegisterKeyRequired() {
-                validKey := functions.IsKeyValidGlobal(clientreq.AccessKey)
-                if !validKey {
-                                errorResponse = models.ErrorResponse{
-                                        Code: http.StatusUnauthorized, Message: "W1R3: Key invalid, or none provided.",
-                                }
-                                returnErrorResponse(w, r, errorResponse)
-                                return
-                }
-        }
-        client, err := RegisterIntClient(clientreq)
-
-        if err != nil {
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
-        w.WriteHeader(http.StatusOK)
-        json.NewEncoder(w).Encode(client)
+	w.Header().Set("Content-Type", "application/json")
+
+	var errorResponse = models.ErrorResponse{
+		Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
+	}
+
+	var clientreq models.IntClient
+
+	//get node from body of request
+	err := json.NewDecoder(r.Body).Decode(&clientreq)
+	if err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	if servercfg.IsRegisterKeyRequired() {
+		validKey := functions.IsKeyValidGlobal(clientreq.AccessKey)
+		if !validKey {
+			errorResponse = models.ErrorResponse{
+				Code: http.StatusUnauthorized, Message: "W1R3: Key invalid, or none provided.",
+			}
+			returnErrorResponse(w, r, errorResponse)
+			return
+		}
+	}
+	client, err := RegisterIntClient(clientreq)
+
+	if err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(client)
 }
 
 func RegisterIntClient(client models.IntClient) (models.IntClient, error) {
@@ -137,71 +136,70 @@ func RegisterIntClient(client models.IntClient) (models.IntClient, error) {
 		}
 		client.Address = newAddress
 	}
-        if client.Network == "" { client.Network = "comms" }
+	if client.Network == "" {
+		client.Network = "comms"
+	}
 	server, err := serverctl.GetServerWGConf()
-        //spew.Dump(server)
+	//spew.Dump(server)
 	if err != nil {
-                return client, err
-        }
+		return client, err
+	}
 	client.ServerPublicEndpoint = server.ServerPublicEndpoint
-        client.ServerAPIPort = server.ServerAPIPort
-        client.ServerPrivateAddress = server.ServerPrivateAddress
-        client.ServerWGPort = server.ServerWGPort
-        client.ServerGRPCPort = server.ServerGRPCPort
-        client.ServerKey = server.ServerKey
-
-        if client.ClientID == "" {
-                clientid := StringWithCharset(7, charset)
-                clientname := "client-" + clientid
-                client.ClientID = clientname
-        }
-
-	//spew.Dump(client)
-	collection := mongoconn.Client.Database("netmaker").Collection("intclients")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	// insert our network into the network table
-	_, err = collection.InsertOne(ctx, client)
-	defer cancel()
+	client.ServerAPIPort = server.ServerAPIPort
+	client.ServerPrivateAddress = server.ServerPrivateAddress
+	client.ServerWGPort = server.ServerWGPort
+	client.ServerGRPCPort = server.ServerGRPCPort
+	client.ServerKey = server.ServerKey
+
+	if client.ClientID == "" {
+		clientid := StringWithCharset(7, charset)
+		clientname := "client-" + clientid
+		client.ClientID = clientname
+	}
 
+	data, err := json.Marshal(&client)
 	if err != nil {
 		return client, err
 	}
+	if err = database.Insert(client.ClientID, string(data), database.INT_CLIENTS_TABLE_NAME); err != nil {
+		return client, err
+	}
 
 	err = serverctl.ReconfigureServerWireGuard()
 
 	return client, err
 }
 func registerIntClient(w http.ResponseWriter, r *http.Request) {
-        w.Header().Set("Content-Type", "application/json")
-
-        var errorResponse = models.ErrorResponse{
-                Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
-        }
-
-        var clientreq models.IntClient
-
-        //get node from body of request
-        err := json.NewDecoder(r.Body).Decode(&clientreq)
-        if err != nil {
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
-        if servercfg.IsRegisterKeyRequired() {
-                validKey := functions.IsKeyValidGlobal(clientreq.AccessKey)
-                if !validKey {
-                                errorResponse = models.ErrorResponse{
-                                        Code: http.StatusUnauthorized, Message: "W1R3: Key invalid, or none provided.",
-                                }
-                                returnErrorResponse(w, r, errorResponse)
-                                return
-                }
-        }
-        client, err := RegisterIntClient(clientreq)
-
-        if err != nil {
-                returnErrorResponse(w, r, formatError(err, "internal"))
-                return
-        }
-        w.WriteHeader(http.StatusOK)
-        json.NewEncoder(w).Encode(client)
+	w.Header().Set("Content-Type", "application/json")
+
+	var errorResponse = models.ErrorResponse{
+		Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
+	}
+
+	var clientreq models.IntClient
+
+	//get node from body of request
+	err := json.NewDecoder(r.Body).Decode(&clientreq)
+	if err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	if servercfg.IsRegisterKeyRequired() {
+		validKey := functions.IsKeyValidGlobal(clientreq.AccessKey)
+		if !validKey {
+			errorResponse = models.ErrorResponse{
+				Code: http.StatusUnauthorized, Message: "W1R3: Key invalid, or none provided.",
+			}
+			returnErrorResponse(w, r, errorResponse)
+			return
+		}
+	}
+	client, err := RegisterIntClient(clientreq)
+
+	if err != nil {
+		returnErrorResponse(w, r, formatError(err, "internal"))
+		return
+	}
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(client)
 }

+ 54 - 151
controllers/networkHttpController.go

@@ -1,7 +1,6 @@
 package controller
 
 import (
-	"context"
 	"encoding/base64"
 	"encoding/json"
 	"errors"
@@ -12,13 +11,10 @@ import (
 
 	"github.com/go-playground/validator/v10"
 	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/functions"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
 	"github.com/gravitl/netmaker/servercfg"
-	"go.mongodb.org/mongo-driver/bson"
-	"go.mongodb.org/mongo-driver/mongo"
-	"go.mongodb.org/mongo-driver/mongo/options"
 )
 
 const ALL_NETWORK_ACCESS = "THIS_USER_HAS_ALL"
@@ -274,14 +270,15 @@ func getNetwork(w http.ResponseWriter, r *http.Request) {
 
 func GetNetwork(name string) (models.Network, error) {
 	var network models.Network
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"netid": name}
-	err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&network)
-	defer cancel()
+	record, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, name)
 	if err != nil {
+		return network, err
+	}
+
+	if err = json.Unmarshal([]byte(record), &network); err != nil {
 		return models.Network{}, err
 	}
+
 	return network, nil
 }
 
@@ -305,61 +302,31 @@ func KeyUpdate(netname string) (models.Network, error) {
 		return models.Network{}, err
 	}
 	network.KeyUpdateTimeStamp = time.Now().Unix()
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"netid": netname}
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"addressrange", network.AddressRange},
-			{"addressrange6", network.AddressRange6},
-			{"displayname", network.DisplayName},
-			{"defaultlistenport", network.DefaultListenPort},
-			{"defaultpostup", network.DefaultPostUp},
-			{"defaultpostdown", network.DefaultPostDown},
-			{"defaultkeepalive", network.DefaultKeepalive},
-			{"keyupdatetimestamp", network.KeyUpdateTimeStamp},
-			{"defaultsaveconfig", network.DefaultSaveConfig},
-			{"defaultinterface", network.DefaultInterface},
-			{"nodeslastmodified", network.NodesLastModified},
-			{"networklastmodified", network.NetworkLastModified},
-			{"allowmanualsignup", network.AllowManualSignUp},
-			{"checkininterval", network.DefaultCheckInInterval},
-		}},
-	}
-	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
-	defer cancel()
+	data, err := json.Marshal(&network)
 	if err != nil {
 		return models.Network{}, err
 	}
+	database.Insert(netname, string(data), database.NETWORKS_TABLE_NAME)
 	return network, nil
 }
 
 //Update a network
 func AlertNetwork(netid string) error {
 
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"netid": netid}
-
 	var network models.Network
-
 	network, err := functions.GetParentNetwork(netid)
 	if err != nil {
 		return err
 	}
 	updatetime := time.Now().Unix()
-	update := bson.D{
-		{"$set", bson.D{
-			{"nodeslastmodified", updatetime},
-			{"networklastmodified", updatetime},
-		}},
+	network.NodesLastModified = updatetime
+	network.NetworkLastModified = updatetime
+	data, err := json.Marshal(&network)
+	if err != nil {
+		return err
 	}
-
-	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
-	defer cancel()
-
-	return err
+	database.Insert(netid, string(data), database.NETWORKS_TABLE_NAME)
+	return nil
 }
 
 //Update a network
@@ -418,24 +385,16 @@ func updateNetworkNodeLimit(w http.ResponseWriter, r *http.Request) {
 
 	_ = json.NewDecoder(r.Body).Decode(&networkChange)
 
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"netid": network.NetID}
-
 	if networkChange.NodeLimit != 0 {
-		update := bson.D{
-			{"$set", bson.D{
-				{"nodelimit", networkChange.NodeLimit},
-			}},
-		}
-		err := collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
-		defer cancel()
+		network.NodeLimit = networkChange.NodeLimit
+		data, err := json.Marshal(&network)
 		if err != nil {
 			returnErrorResponse(w, r, formatError(err, "badrequest"))
 			return
 		}
+		database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME)
+		functions.PrintUserLog(r.Header.Get("user"), "updated network node limit on, "+netname, 1)
 	}
-	functions.PrintUserLog(r.Header.Get("user"), "updated network node limit on, "+netname, 1)
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(network)
 }
@@ -500,42 +459,17 @@ func UpdateNetwork(networkChange models.NetworkUpdate, network models.Network) (
 		haschange = true
 	}
 
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"netid": network.NetID}
-
 	if haschange {
 		network.SetNetworkLastModified()
 	}
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"addressrange", network.AddressRange},
-			{"addressrange6", network.AddressRange6},
-			{"displayname", network.DisplayName},
-			{"defaultlistenport", network.DefaultListenPort},
-			{"defaultpostup", network.DefaultPostUp},
-			{"defaultpostdown", network.DefaultPostDown},
-			{"defaultkeepalive", network.DefaultKeepalive},
-			{"defaultsaveconfig", network.DefaultSaveConfig},
-			{"defaultinterface", network.DefaultInterface},
-			{"nodeslastmodified", network.NodesLastModified},
-			{"networklastmodified", network.NetworkLastModified},
-			{"allowmanualsignup", network.AllowManualSignUp},
-			{"localrange", network.LocalRange},
-			{"islocal", network.IsLocal},
-			{"isdualstack", network.IsDualStack},
-			{"checkininterval", network.DefaultCheckInInterval},
-		}},
-	}
-
-	err := collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
-	defer cancel()
 
+	data, err := json.Marshal(&network)
 	if err != nil {
 		return models.Network{}, err
 	}
 
+	database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME)
+
 	//Cycles through nodes and gives them new IP's based on the new range
 	//Pretty cool, but also pretty inefficient currently
 	if hasrangeupdate {
@@ -565,7 +499,7 @@ func deleteNetwork(w http.ResponseWriter, r *http.Request) {
 
 	var params = mux.Vars(r)
 	network := params["networkname"]
-	count, err := DeleteNetwork(network)
+	err := DeleteNetwork(network)
 
 	if err != nil {
 		errtype := "badrequest"
@@ -577,34 +511,20 @@ func deleteNetwork(w http.ResponseWriter, r *http.Request) {
 	}
 	functions.PrintUserLog(r.Header.Get("user"), "deleted network "+network, 1)
 	w.WriteHeader(http.StatusOK)
-	json.NewEncoder(w).Encode(count)
+	json.NewEncoder(w).Encode("success")
 }
 
-func DeleteNetwork(network string) (*mongo.DeleteResult, error) {
-	none := &mongo.DeleteResult{}
+func DeleteNetwork(network string) error {
 
 	nodecount, err := functions.GetNetworkNodeNumber(network)
 	if err != nil {
-		//returnErrorResponse(w, r, formatError(err, "internal"))
-		return none, err
+		return err
 	} else if nodecount > 0 {
-		//errorResponse := models.ErrorResponse{
-		//	Code: http.StatusForbidden, Message: "W1R3: Node check failed. All nodes must be deleted before deleting network.",
-		//}
-		//returnErrorResponse(w, r, errorResponse)
-		return none, errors.New("Node check failed. All nodes must be deleted before deleting network")
+		return errors.New("node check failed. All nodes must be deleted before deleting network")
 	}
 
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	filter := bson.M{"netid": network}
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	deleteResult, err := collection.DeleteOne(ctx, filter)
-	defer cancel()
-	if err != nil {
-		//returnErrorResponse(w, r, formatError(err, "internal"))
-		return none, err
-	}
-	return deleteResult, nil
+	database.DeleteRecord(database.NETWORKS_TABLE_NAME, network)
+	return err
 }
 
 //Create a network
@@ -655,15 +575,14 @@ func CreateNetwork(network models.Network) error {
 	network.SetNetworkLastModified()
 	network.KeyUpdateTimeStamp = time.Now().Unix()
 
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	// insert our network into the network table
-	_, err = collection.InsertOne(ctx, network)
-	defer cancel()
+	data, err := json.Marshal(&network)
 	if err != nil {
 		return err
 	}
+	if err = database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME); err != nil {
+		return err
+	}
+
 	return nil
 }
 
@@ -718,7 +637,7 @@ func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models
 
 	for _, key := range checkkeys {
 		if key.Name == accesskey.Name {
-			return models.AccessKey{}, errors.New("Duplicate AccessKey Name")
+			return models.AccessKey{}, errors.New("duplicate AccessKey Name")
 		}
 	}
 	privAddr := ""
@@ -773,24 +692,16 @@ func CreateAccessKey(accesskey models.AccessKey, network models.Network) (models
 		}
 		return models.AccessKey{}, err
 	}
+
 	network.AccessKeys = append(network.AccessKeys, accesskey)
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	// Create filter
-	filter := bson.M{"netid": network.NetID}
-	// Read update model from body request
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"accesskeys", network.AccessKeys},
-		}},
-	}
-	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
-	defer cancel()
-	if err != nil {
-		//returnErrorResponse(w, r, formatError(err, "internal"))
+	data, err := json.Marshal(&network)
+	if err != nil {
+		return models.AccessKey{}, err
+	}
+	if err = database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME); err != nil {
 		return models.AccessKey{}, err
 	}
+
 	return accesskey, nil
 }
 
@@ -859,12 +770,11 @@ func getAccessKeys(w http.ResponseWriter, r *http.Request) {
 }
 func GetKeys(net string) ([]models.AccessKey, error) {
 
-	var network models.Network
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"netid": net}
-	err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&network)
-	defer cancel()
+	record, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, net)
+	if err != nil {
+		return []models.AccessKey{}, err
+	}
+	network, err := functions.ParseNetwork(record)
 	if err != nil {
 		return []models.AccessKey{}, err
 	}
@@ -904,21 +814,14 @@ func DeleteKey(keyname, netname string) error {
 	if !found {
 		return errors.New("key " + keyname + " does not exist")
 	}
-
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	// Create filter
-	filter := bson.M{"netid": netname}
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"accesskeys", updatedKeys},
-		}},
-	}
-	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&network)
-	defer cancel()
+	network.AccessKeys = updatedKeys
+	data, err := json.Marshal(&network)
 	if err != nil {
 		return err
 	}
+	if err := database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME); err != nil {
+		return err
+	}
+
 	return nil
 }

+ 4 - 10
controllers/networkHttpController_test.go

@@ -20,17 +20,15 @@ func deleteNet(t *testing.T) {
 	assert.Nil(t, err)
 	for _, node := range nodes {
 		t.Log("deleting node", node.Name)
-		result, err := DeleteNode(node.MacAddress, node.Network)
+		err := DeleteNode(node.MacAddress, node.Network)
 		assert.Nil(t, err)
-		assert.True(t, result)
 	}
 	dns, err := GetAllDNS()
 	assert.Nil(t, err)
 	for _, entry := range dns {
 		t.Log("deleting dns enty", entry.Name, entry.Network)
-		success, err := DeleteDNS(entry.Name, entry.Network)
+		err := DeleteDNS(entry.Name, entry.Network)
 		assert.Nil(t, err)
-		assert.True(t, success)
 	}
 	networks, _ := functions.ListNetworks()
 	for _, network := range networks {
@@ -78,10 +76,8 @@ func TestGetDeleteNetwork(t *testing.T) {
 		assert.Equal(t, "skynet", network.NetID)
 	})
 	t.Run("DeleteExistingNetwork", func(t *testing.T) {
-		result, err := DeleteNetwork("skynet")
+		err := DeleteNetwork("skynet")
 		assert.Nil(t, err)
-		assert.Equal(t, int64(1), result.DeletedCount)
-		t.Log(result.DeletedCount)
 	})
 	t.Run("GetNonExistantNetwork", func(t *testing.T) {
 		network, err := GetNetwork("skynet")
@@ -90,10 +86,8 @@ func TestGetDeleteNetwork(t *testing.T) {
 		assert.Equal(t, "", network.NetID)
 	})
 	t.Run("NonExistantNetwork", func(t *testing.T) {
-		result, err := DeleteNetwork("skynet")
+		err := DeleteNetwork("skynet")
 		assert.Nil(t, err)
-		assert.Equal(t, int64(0), result.DeletedCount)
-		t.Log(result.DeletedCount)
 	})
 }
 func TestGetNetwork(t *testing.T) {

+ 65 - 67
controllers/nodeGrpcController.go

@@ -3,17 +3,16 @@ package controller
 import (
 	"context"
 	"fmt"
+
 	"github.com/gravitl/netmaker/functions"
 	nodepb "github.com/gravitl/netmaker/grpc"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/servercfg"
-	"go.mongodb.org/mongo-driver/mongo"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
 )
 
 type NodeServiceServer struct {
-	NodeDB *mongo.Collection
 	nodepb.UnimplementedNodeServiceServer
 }
 
@@ -46,32 +45,33 @@ func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.ReadNodeRe
 
 	response := &nodepb.ReadNodeRes{
 		Node: &nodepb.Node{
-			Macaddress:      node.MacAddress,
-			Name:            node.Name,
-			Address:         node.Address,
-			Address6:        node.Address6,
-			Endpoint:        node.Endpoint,
-			Password:        node.Password,
-			Nodenetwork:     node.Network,
-			Interface:       node.Interface,
-			Localaddress:    node.LocalAddress,
-			Postdown:        node.PostDown,
-			Postup:          node.PostUp,
-			Checkininterval: node.CheckInInterval,
-			Dnsoff:          !servercfg.IsDNSMode(),
-			Ispending:       node.IsPending,
-			Isingressgateway:       node.IsIngressGateway,
-			Ingressgatewayrange:       node.IngressGatewayRange,
-			Publickey:       node.PublicKey,
-			Listenport:      node.ListenPort,
-			Keepalive:       node.PersistentKeepalive,
-			Islocal:         localvar,
-			Isdualstack:     dualvar,
-			Localrange:      network.LocalRange,
+			Macaddress:          node.MacAddress,
+			Name:                node.Name,
+			Address:             node.Address,
+			Address6:            node.Address6,
+			Endpoint:            node.Endpoint,
+			Password:            node.Password,
+			Nodenetwork:         node.Network,
+			Interface:           node.Interface,
+			Localaddress:        node.LocalAddress,
+			Postdown:            node.PostDown,
+			Postup:              node.PostUp,
+			Checkininterval:     node.CheckInInterval,
+			Dnsoff:              !servercfg.IsDNSMode(),
+			Ispending:           node.IsPending,
+			Isingressgateway:    node.IsIngressGateway,
+			Ingressgatewayrange: node.IngressGatewayRange,
+			Publickey:           node.PublicKey,
+			Listenport:          node.ListenPort,
+			Keepalive:           node.PersistentKeepalive,
+			Islocal:             localvar,
+			Isdualstack:         dualvar,
+			Localrange:          network.LocalRange,
 		},
 	}
 	return response, nil
 }
+
 /*
 func (s *NodeServiceServer) GetConn(ctx context.Context, data *nodepb.Client) (*nodepb.Client, error) {
         // Get the protobuf node type from the protobuf request type
@@ -356,9 +356,9 @@ func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.DeleteNo
 	macaddress := req.GetMacaddress()
 	network := req.GetNetworkName()
 
-	success, err := DeleteNode(macaddress, network)
+	err := DeleteNode(macaddress, network)
 
-	if err != nil || !success {
+	if err != nil {
 		fmt.Println("Error deleting node.")
 		fmt.Println(err)
 		return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find/delete node with mac address %s", macaddress))
@@ -381,7 +381,6 @@ func (s *NodeServiceServer) GetPeers(req *nodepb.GetPeersReq, stream nodepb.Node
 	// Initiate a NodeItem type to write decoded data to
 	//data := &models.PeersResponse{}
 	// collection.Find returns a cursor for our (empty) query
-	//cursor, err := s.NodeDB.Find(context.Background(), bson.M{})
 	peers, err := GetPeersList(req.GetNetwork())
 
 	if err != nil {
@@ -393,15 +392,15 @@ func (s *NodeServiceServer) GetPeers(req *nodepb.GetPeersReq, stream nodepb.Node
 		// If no error is found send node over stream
 		stream.Send(&nodepb.GetPeersRes{
 			Peers: &nodepb.PeersResponse{
-				Address:      peers[i].Address,
-				Address6:     peers[i].Address6,
-				Endpoint:     peers[i].Endpoint,
+				Address:            peers[i].Address,
+				Address6:           peers[i].Address6,
+				Endpoint:           peers[i].Endpoint,
 				Egressgatewayrange: peers[i].EgressGatewayRange,
 				Isegressgateway:    peers[i].IsEgressGateway,
-				Publickey:    peers[i].PublicKey,
-				Keepalive:    peers[i].KeepAlive,
-				Listenport:   peers[i].ListenPort,
-				Localaddress: peers[i].LocalAddress,
+				Publickey:          peers[i].PublicKey,
+				Keepalive:          peers[i].KeepAlive,
+				Listenport:         peers[i].ListenPort,
+				Localaddress:       peers[i].LocalAddress,
 			},
 		})
 	}
@@ -420,41 +419,40 @@ func (s *NodeServiceServer) GetPeers(req *nodepb.GetPeersReq, stream nodepb.Node
 }
 
 func (s *NodeServiceServer) GetExtPeers(req *nodepb.GetExtPeersReq, stream nodepb.NodeService_GetExtPeersServer) error {
-        // Initiate a NodeItem type to write decoded data to
-        //data := &models.PeersResponse{}
-        // collection.Find returns a cursor for our (empty) query
-        //cursor, err := s.NodeDB.Find(context.Background(), bson.M{})
-        peers, err := GetExtPeersList(req.GetNetwork(), req.GetMacaddress())
+	// Initiate a NodeItem type to write decoded data to
+	//data := &models.PeersResponse{}
+	// collection.Find returns a cursor for our (empty) query
+	peers, err := GetExtPeersList(req.GetNetwork(), req.GetMacaddress())
 
-        if err != nil {
-                return status.Errorf(codes.Internal, fmt.Sprintf("Unknown internal error: %v", err))
-        }
-        // cursor.Next() returns a boolean, if false there are no more items and loop will break
-        for i := 0; i < len(peers); i++ {
-
-                // If no error is found send node over stream
-                stream.Send(&nodepb.GetExtPeersRes{
-                        Extpeers: &nodepb.ExtPeersResponse{
-                                Address:      peers[i].Address,
-                                Address6:     peers[i].Address6,
-                                Endpoint:     peers[i].Endpoint,
-                                Publickey:    peers[i].PublicKey,
-                                Keepalive:    peers[i].KeepAlive,
-                                Listenport:   peers[i].ListenPort,
-                                Localaddress: peers[i].LocalAddress,
-                        },
-                })
-        }
+	if err != nil {
+		return status.Errorf(codes.Internal, fmt.Sprintf("Unknown internal error: %v", err))
+	}
+	// cursor.Next() returns a boolean, if false there are no more items and loop will break
+	for i := 0; i < len(peers); i++ {
 
-        node, err := functions.GetNodeByMacAddress(req.GetNetwork(), req.GetMacaddress())
-        if err != nil {
-                return status.Errorf(codes.Internal, fmt.Sprintf("Could not get node: %v", err))
-        }
+		// If no error is found send node over stream
+		stream.Send(&nodepb.GetExtPeersRes{
+			Extpeers: &nodepb.ExtPeersResponse{
+				Address:      peers[i].Address,
+				Address6:     peers[i].Address6,
+				Endpoint:     peers[i].Endpoint,
+				Publickey:    peers[i].PublicKey,
+				Keepalive:    peers[i].KeepAlive,
+				Listenport:   peers[i].ListenPort,
+				Localaddress: peers[i].LocalAddress,
+			},
+		})
+	}
 
-        err = TimestampNode(node, false, true, false)
-        if err != nil {
-                return status.Errorf(codes.Internal, fmt.Sprintf("Internal error occurred: %v", err))
-        }
+	node, err := functions.GetNodeByMacAddress(req.GetNetwork(), req.GetMacaddress())
+	if err != nil {
+		return status.Errorf(codes.Internal, fmt.Sprintf("Could not get node: %v", err))
+	}
 
-        return nil
+	err = TimestampNode(node, false, true, false)
+	if err != nil {
+		return status.Errorf(codes.Internal, fmt.Sprintf("Internal error occurred: %v", err))
+	}
+
+	return nil
 }

+ 105 - 214
controllers/nodeHttpController.go

@@ -1,21 +1,17 @@
 package controller
 
 import (
-	"context"
 	"encoding/json"
 	"errors"
-	"fmt"
 	"log"
 	"net/http"
 	"strings"
 	"time"
 
 	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/functions"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
-	"go.mongodb.org/mongo-driver/bson"
-	"go.mongodb.org/mongo-driver/mongo/options"
 	"golang.org/x/crypto/bcrypt"
 )
 
@@ -41,6 +37,8 @@ func nodeHandlers(r *mux.Router) {
 //Node authenticates using its password and retrieves a JWT for authorization.
 func authenticate(response http.ResponseWriter, request *http.Request) {
 
+	var params = mux.Vars(request)
+	networkname := params["network"]
 	//Auth request consists of Mac Address and Password (from node that is authorizing
 	//in case of Master, auth is ignored and mac is set to "mastermac"
 	var authRequest models.AuthParams
@@ -72,11 +70,21 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
 		} else {
 
 			//Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API untill approved).
-			collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-			ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-			var err = collection.FindOne(ctx, bson.M{"macaddress": authRequest.MacAddress, "ispending": false}).Decode(&result)
-
-			defer cancel()
+			collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
+			if err != nil {
+				errorResponse.Code = http.StatusBadRequest
+				errorResponse.Message = err.Error()
+				returnErrorResponse(response, request, errorResponse)
+				return
+			}
+			for _, value := range collection {
+				if err := json.Unmarshal([]byte(value), &result); err != nil {
+					continue
+				}
+				if result.MacAddress == authRequest.MacAddress && !result.IsPending && result.Network == networkname {
+					break
+				}
+			}
 
 			if err != nil {
 				errorResponse.Code = http.StatusBadRequest
@@ -286,32 +294,20 @@ func getNetworkNodes(w http.ResponseWriter, r *http.Request) {
 
 func GetNetworkNodes(network string) ([]models.Node, error) {
 	var nodes []models.Node
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"network": network}
-	//Filtering out the ID field cuz Dillon doesn't like it. May want to filter out other fields in the future
-	cur, err := collection.Find(ctx, filter, options.Find().SetProjection(bson.M{"_id": 0}))
-	if err != nil {
-		return []models.Node{}, err
-	}
-	defer cancel()
-	for cur.Next(context.TODO()) {
-		//Using a different model for the Node (other than regular node).
-		//Either we should do this for ALL structs (so Networks and Keys)
-		//OR we should just use the original struct
-		//My preference is to make some new return structs
-		//TODO: Think about this. Not an immediate concern. Just need to get some consistency eventually
+	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
+	if err != nil {
+		return nodes, err
+	}
+	for _, value := range collection {
+
 		var node models.Node
-		err := cur.Decode(&node)
+		err := json.Unmarshal([]byte(value), &node)
 		if err != nil {
-			return []models.Node{}, err
+			continue
+		}
+		if node.Network == network {
+			nodes = append(nodes, node)
 		}
-		// add item our array of nodes
-		nodes = append(nodes, node)
-	}
-	//TODO: Another fatal error we should take care of.
-	if err := cur.Err(); err != nil {
-		return []models.Node{}, err
 	}
 	return nodes, nil
 }
@@ -356,35 +352,22 @@ func checkIn(w http.ResponseWriter, r *http.Request) {
 	w.WriteHeader(http.StatusOK)
 	json.NewEncoder(w).Encode(node)
 }
-func CheckIn(network, macaddress string) (models.Node, error) {
+func CheckIn(network string, macaddress string) (models.Node, error) {
 	var node models.Node
 
-	//Retrieves node with DB Call which is inefficient. Let's just get the time and set it.
-	//node = functions.GetNodeByMacAddress(params["network"], params["macaddress"])
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"macaddress": macaddress, "network": network}
-	//old code was inefficient, this is all we need.
-	time := time.Now().Unix()
-	//node.SetLastCheckIn()
-	// prepare update model with new time
-	update := bson.D{
-		{"$set", bson.D{
-			{"lastcheckin", time},
-		}},
-	}
-	err := collection.FindOneAndUpdate(ctx, filter, update).Decode(&node)
-	defer cancel()
+	node, err := GetNode(macaddress, network)
+	key, err := functions.GetRecordKey(macaddress, network)
 	if err != nil {
-		return models.Node{}, err
+		return node, err
 	}
-	//TODO: check node last modified vs network last modified
-	//Get Updated node to return
-	node, err = GetNode(macaddress, network)
+	time := time.Now().Unix()
+	node.LastCheckIn = time
+	data, err := json.Marshal(&node)
 	if err != nil {
-		return models.Node{}, err
+		return node, err
 	}
-	return node, nil
+	err = database.Insert(key, string(data), database.NODES_TABLE_NAME)
+	return node, err
 }
 
 //Get an individual node. Nothin fancy here folks.
@@ -413,7 +396,7 @@ func getLastModified(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "application/json")
 
 	var params = mux.Vars(r)
-	network, err := GetLastModified(params["network"])
+	network, err := GetNetwork(params["network"])
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
@@ -423,20 +406,6 @@ func getLastModified(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(network.NodesLastModified)
 }
 
-func GetLastModified(network string) (models.Network, error) {
-	var net models.Network
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"netid": network}
-	err := collection.FindOne(ctx, filter).Decode(&net)
-	defer cancel()
-	if err != nil {
-		fmt.Println(err)
-		return models.Network{}, err
-	}
-	return net, nil
-}
-
 //This one's a doozy
 //To create a node
 //Must have valid key and be unique
@@ -538,24 +507,19 @@ func UncordonNode(network, macaddress string) (models.Node, error) {
 	if err != nil {
 		return models.Node{}, err
 	}
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	// Create filter
-	filter := bson.M{"macaddress": macaddress, "network": network}
 	node.SetLastModified()
-	fmt.Println("Uncordoning node " + node.Name)
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"ispending", false},
-		}},
+	node.IsPending = false
+	data, err := json.Marshal(&node)
+	if err != nil {
+		return node, err
 	}
-	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&node)
-	defer cancel()
+	key, err := functions.GetRecordKey(node.MacAddress, node.Network)
 	if err != nil {
-		return models.Node{}, err
+		return node, err
 	}
-	return node, nil
+
+	err = database.Insert(key, string(data), database.NODES_TABLE_NAME)
+	return node, err
 }
 
 func createEgressGateway(w http.ResponseWriter, r *http.Request) {
@@ -588,62 +552,42 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
 	if err != nil {
 		return models.Node{}, err
 	}
-	var nodechange models.Node
-	nodechange.IsEgressGateway = true
-	nodechange.EgressGatewayRanges = gateway.Ranges
-	nodechange.PostUp = "iptables -A FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -A 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"
+	node.IsEgressGateway = true
+	node.EgressGatewayRanges = gateway.Ranges
+	postUpCmd := "iptables -A FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -A POSTROUTING -o " + gateway.Interface + " -j MASQUERADE"
+	postDownCmd := "iptables -D FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -D POSTROUTING -o " + gateway.Interface + " -j MASQUERADE"
 	if gateway.PostUp != "" {
-		nodechange.PostUp = gateway.PostUp
+		postUpCmd = gateway.PostUp
 	}
 	if gateway.PostDown != "" {
-		nodechange.PostDown = gateway.PostDown
+		postDownCmd = gateway.PostDown
 	}
 	if node.PostUp != "" {
-		if !strings.Contains(node.PostUp, nodechange.PostUp) {
-			nodechange.PostUp = node.PostUp + "; " + nodechange.PostUp
-		} else {
-			nodechange.PostUp = node.PostUp
+		if !strings.Contains(node.PostUp, postUpCmd) {
+			node.PostUp = node.PostUp + "; " + postUpCmd
 		}
 	}
 	if node.PostDown != "" {
-		if !strings.Contains(node.PostDown, nodechange.PostDown) {
-			nodechange.PostDown = node.PostDown + "; " + nodechange.PostDown
-		} else {
-			nodechange.PostDown = node.PostDown
+		if !strings.Contains(node.PostDown, postDownCmd) {
+			node.PostDown = node.PostDown + "; " + postDownCmd
 		}
 	}
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	// Create filter
-	filter := bson.M{"macaddress": gateway.NodeID, "network": gateway.NetID}
-	nodechange.SetLastModified()
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"postup", nodechange.PostUp},
-			{"postdown", nodechange.PostDown},
-			{"isegressgateway", nodechange.IsEgressGateway},
-			{"egressgatewayranges", nodechange.EgressGatewayRanges},
-			{"lastmodified", nodechange.LastModified},
-		}},
-	}
-	var nodeupdate models.Node
-	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&nodeupdate)
-	defer cancel()
+	key, err := functions.GetRecordKey(gateway.NodeID, gateway.NetID)
 	if err != nil {
-		return models.Node{}, err
+		return node, err
 	}
-	err = SetNetworkNodesLastModified(gateway.NetID)
+	nodeData, err := json.Marshal(&node)
 	if err != nil {
-		return models.Node{}, err
+		return node, err
 	}
-	//Get updated values to return
-	node, err = functions.GetNodeByMacAddress(gateway.NetID, gateway.NodeID)
+	node.SetLastModified()
+	err = database.Insert(key, string(nodeData), database.NODES_TABLE_NAME)
+	// prepare update model.
 	if err != nil {
 		return models.Node{}, err
 	}
-	return node, nil
+	err = SetNetworkNodesLastModified(gateway.NetID)
+	return node, err
 }
 
 func ValidateEgressGateway(gateway models.EgressGatewayRequest) error {
@@ -677,44 +621,29 @@ func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
 
 func DeleteEgressGateway(network, macaddress string) (models.Node, error) {
 
-	var nodeupdate models.Node
-	var nodechange models.Node
 	node, err := functions.GetNodeByMacAddress(network, macaddress)
 	if err != nil {
 		return models.Node{}, err
 	}
 
-	nodechange.IsEgressGateway = false
-	nodechange.EgressGatewayRanges = []string{}
-	nodechange.PostUp = ""
-	nodechange.PostDown = ""
-
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	// Create filter
-	filter := bson.M{"macaddress": macaddress, "network": network}
-	nodechange.SetLastModified()
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"postup", nodechange.PostUp},
-			{"postdown", nodechange.PostDown},
-			{"isegressgateway", nodechange.IsEgressGateway},
-			{"egressgatewayranges", nodechange.EgressGatewayRanges},
-			{"lastmodified", nodechange.LastModified},
-		}},
-	}
-	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&nodeupdate)
-	defer cancel()
+	node.IsEgressGateway = false
+	node.EgressGatewayRanges = []string{}
+	node.PostUp = ""
+	node.PostDown = ""
+	node.SetLastModified()
+	key, err := functions.GetRecordKey(node.MacAddress, node.Network)
 	if err != nil {
 		return models.Node{}, err
 	}
-	err = SetNetworkNodesLastModified(network)
+	data, err := json.Marshal(&node)
 	if err != nil {
 		return models.Node{}, err
 	}
-	//Get updated values to return
-	node, err = functions.GetNodeByMacAddress(network, macaddress)
+	err = database.Insert(key, string(data), database.NODES_TABLE_NAME)
+	if err != nil {
+		return models.Node{}, err
+	}
+	err = SetNetworkNodesLastModified(network)
 	if err != nil {
 		return models.Node{}, err
 	}
@@ -749,58 +678,35 @@ func CreateIngressGateway(netid string, macaddress string) (models.Node, error)
 		log.Println("Could not find network.")
 		return models.Node{}, err
 	}
-	var nodechange models.Node
-	nodechange.IngressGatewayRange = network.AddressRange
-	nodechange.PostUp = "iptables -A FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -A POSTROUTING -o " + node.Interface + " -j MASQUERADE"
-	nodechange.PostDown = "iptables -D FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -D POSTROUTING -o " + node.Interface + " -j MASQUERADE"
+	node.IngressGatewayRange = network.AddressRange
+	postUpCmd := "iptables -A FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -A POSTROUTING -o " + node.Interface + " -j MASQUERADE"
+	postDownCmd := "iptables -D FORWARD -i " + node.Interface + " -j ACCEPT; iptables -t nat -D POSTROUTING -o " + node.Interface + " -j MASQUERADE"
 	if node.PostUp != "" {
-		if !strings.Contains(node.PostUp, nodechange.PostUp) {
-			nodechange.PostUp = node.PostUp + "; " + nodechange.PostUp
-		} else {
-			nodechange.PostUp = node.PostUp
+		if !strings.Contains(node.PostUp, postUpCmd) {
+			node.PostUp = node.PostUp + "; " + postUpCmd
 		}
 	}
 	if node.PostDown != "" {
-		if !strings.Contains(node.PostDown, nodechange.PostDown) {
-			nodechange.PostDown = node.PostDown + "; " + nodechange.PostDown
-		} else {
-			nodechange.PostDown = node.PostDown
+		if !strings.Contains(node.PostDown, postDownCmd) {
+			node.PostDown = node.PostDown + "; " + postDownCmd
 		}
 	}
-
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	// Create filter
-	filter := bson.M{"macaddress": macaddress, "network": netid}
 	node.SetLastModified()
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"postup", nodechange.PostUp},
-			{"postdown", nodechange.PostDown},
-			{"isingressgateway", true},
-			{"ingressgatewayrange", nodechange.IngressGatewayRange},
-			{"lastmodified", node.LastModified},
-		}},
-	}
-	var nodeupdate models.Node
-	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&nodeupdate)
-	defer cancel()
-	if err != nil {
-		log.Println("error updating node to gateway")
+
+	key, err := functions.GetRecordKey(node.MacAddress, node.Network)
+	if err != nil {
 		return models.Node{}, err
 	}
-	err = SetNetworkNodesLastModified(netid)
+	data, err := json.Marshal(&node)
 	if err != nil {
-		return node, err
+		return models.Node{}, err
 	}
-	//Get updated values to return
-	node, err = functions.GetNodeByMacAddress(netid, macaddress)
+	err = database.Insert(key, string(data), database.NODES_TABLE_NAME)
 	if err != nil {
-		log.Println("error finding node after update")
-		return node, err
+		return models.Node{}, err
 	}
-	return node, nil
+	err = SetNetworkNodesLastModified(netid)
+	return node, err
 }
 
 func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
@@ -819,38 +725,26 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
 
 func DeleteIngressGateway(network, macaddress string) (models.Node, error) {
 
-	var nodeupdate models.Node
 	node, err := functions.GetNodeByMacAddress(network, macaddress)
 	if err != nil {
 		return models.Node{}, err
 	}
-
-	collection := mongoconn.Client.Database("netmaker").Collection("nodes")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	// Create filter
-	filter := bson.M{"macaddress": macaddress, "network": network}
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"lastmodified", time.Now().Unix()},
-			{"isingressgateway", false},
-		}},
-	}
-	err = collection.FindOneAndUpdate(ctx, filter, update).Decode(&nodeupdate)
-	defer cancel()
+	node.LastModified = time.Now().Unix()
+	node.IsIngressGateway = false
+	key, err := functions.GetRecordKey(node.MacAddress, node.Network)
 	if err != nil {
 		return models.Node{}, err
 	}
-	err = SetNetworkNodesLastModified(network)
+	data, err := json.Marshal(&node)
 	if err != nil {
 		return models.Node{}, err
 	}
-	//Get updated values to return
-	node, err = functions.GetNodeByMacAddress(network, macaddress)
+	err = database.Insert(key, string(data), database.NODES_TABLE_NAME)
 	if err != nil {
 		return models.Node{}, err
 	}
-	return node, nil
+	err = SetNetworkNodesLastModified(network)
+	return node, err
 }
 
 func updateNode(w http.ResponseWriter, r *http.Request) {
@@ -904,15 +798,12 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
 	// get params
 	var params = mux.Vars(r)
 
-	success, err := DeleteNode(params["macaddress"], params["network"])
+	err := DeleteNode(params["macaddress"], params["network"])
 
 	if err != nil {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
-	} else if !success {
-		err = errors.New("Could not delete node " + params["macaddress"])
-		returnErrorResponse(w, r, formatError(err, "internal"))
-		return
 	}
+	functions.PrintUserLog(r.Header.Get("user"), "Deleted node "+params["macaddress"]+" from network "+params["network"], 1)
 	returnSuccessResponse(w, r, params["macaddress"]+" deleted.")
 }

+ 54 - 119
controllers/userHttpController.go

@@ -1,22 +1,17 @@
 package controller
 
 import (
-	"context"
 	"encoding/json"
 	"errors"
 	"fmt"
 	"net/http"
 	"strings"
-	"time"
 
 	"github.com/go-playground/validator/v10"
 	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/functions"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
-	"go.mongodb.org/mongo-driver/bson"
-	"go.mongodb.org/mongo-driver/mongo"
-	"go.mongodb.org/mongo-driver/mongo/options"
 	"golang.org/x/crypto/bcrypt"
 )
 
@@ -87,30 +82,24 @@ func authenticateUser(response http.ResponseWriter, request *http.Request) {
 func VerifyAuthRequest(authRequest models.UserAuthParams) (string, error) {
 	var result models.User
 	if authRequest.UserName == "" {
-		return "", errors.New("Username can't be empty")
+		return "", errors.New("username can't be empty")
 	} else if authRequest.Password == "" {
-		return "", errors.New("Password can't be empty")
+		return "", errors.New("password can't be empty")
 	}
 	//Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API untill approved).
-	collection := mongoconn.Client.Database("netmaker").Collection("users")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	var err = collection.FindOne(ctx, bson.M{"username": authRequest.UserName}).Decode(&result)
-
-	defer cancel()
+	record, err := database.FetchRecord(database.USERS_TABLE_NAME, authRequest.UserName)
 	if err != nil {
-		return "", errors.New("User " + authRequest.UserName + " not found")
+		return "", errors.New("user " + authRequest.UserName + " not found")
+	}
+	if err = json.Unmarshal([]byte(record), &result); err != nil {
+		return "", errors.New("user " + authRequest.UserName + " not found")
 	}
-	// This is a a useless test as cannot create user that is not an an admin
-	//if !result.IsAdmin {
-	//	return "", errors.New("User is not an admin")
-	//}
 
 	//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...
 	//TODO: Consider a way of hashing the password client side before sending, or using certificates
-	err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password))
-	if err != nil {
-		return "", errors.New("Wrong Password")
+	if err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password)); err != nil {
+		return "", errors.New("wrong password")
 	}
 
 	//Create a new JWT for the node
@@ -193,27 +182,23 @@ func ValidateUserToken(token string, user string, adminonly bool) error {
 
 func HasAdmin() (bool, error) {
 
-	collection := mongoconn.Client.Database("netmaker").Collection("users")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	filter := bson.M{"isadmin": true}
-
-	//Filtering out the ID field cuz Dillon doesn't like it. May want to filter out other fields in the future
-	var result bson.M
-
-	err := collection.FindOne(ctx, filter).Decode(&result)
-
-	defer cancel()
-
+	collection, err := database.FetchRecords(database.USERS_TABLE_NAME)
 	if err != nil {
-		if err == mongo.ErrNoDocuments {
-			return false, nil
-		}
 		return false, err
-		fmt.Println(err)
 	}
-	return true, err
+
+	for _, value := range collection { // filter for isadmin true
+		var user models.User
+		err = json.Unmarshal([]byte(value), &user)
+		if err != nil {
+			continue
+		}
+		if user.IsAdmin {
+			return true, nil
+		}
+	}
+
+	return false, err
 }
 
 func hasAdmin(w http.ResponseWriter, r *http.Request) {
@@ -231,16 +216,13 @@ func hasAdmin(w http.ResponseWriter, r *http.Request) {
 func GetUser(username string) (models.User, error) {
 
 	var user models.User
-
-	collection := mongoconn.Client.Database("netmaker").Collection("users")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	filter := bson.M{"username": username}
-	err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&user)
-
-	defer cancel()
-
+	record, err := database.FetchRecord(database.USERS_TABLE_NAME, username)
+	if err != nil {
+		return user, err
+	}
+	if err = json.Unmarshal([]byte(record), &user); err != nil {
+		return models.User{}, err
+	}
 	return user, err
 }
 
@@ -248,34 +230,22 @@ func GetUsers() ([]models.User, error) {
 
 	var users []models.User
 
-	collection := mongoconn.Client.Database("netmaker").Collection("users")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	cur, err := collection.Find(ctx, bson.M{}, options.Find().SetProjection(bson.M{"_id": 0}))
+	collection, err := database.FetchRecords(database.USERS_TABLE_NAME)
 
 	if err != nil {
 		return users, err
 	}
 
-	defer cancel()
-
-	for cur.Next(context.TODO()) {
+	for _, value := range collection {
 
 		var user models.User
-		err := cur.Decode(&user)
+		err = json.Unmarshal([]byte(value), &user)
 		if err != nil {
-			return users, err
+			continue // get users
 		}
-
-		// add network our array
 		users = append(users, user)
 	}
 
-	if err := cur.Err(); err != nil {
-		return users, err
-	}
-
 	return users, err
 }
 
@@ -334,12 +304,11 @@ func CreateUser(user models.User) (models.User, error) {
 	}
 
 	// connect db
-	collection := mongoconn.Client.Database("netmaker").Collection("users")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	// insert our node to the node db.
-	_, err = collection.InsertOne(ctx, user)
-	defer cancel()
+	data, err := json.Marshal(&user)
+	if err != nil {
+		return user, err
+	}
+	err = database.Insert(user.UserName, string(data), database.USERS_TABLE_NAME)
 
 	return user, err
 }
@@ -405,38 +374,18 @@ func UpdateUser(userchange models.User, user models.User) (models.User, error) {
 
 		user.Password = userchange.Password
 	}
-	//collection := mongoconn.ConnectDB()
-	collection := mongoconn.Client.Database("netmaker").Collection("users")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	// Create filter
-	filter := bson.M{"username": queryUser}
-
-	fmt.Println("Updating User " + user.UserName)
-
-	// prepare update model.
-	update := bson.D{
-		{"$set", bson.D{
-			{"username", user.UserName},
-			{"password", user.Password},
-			{"networks", user.Networks},
-			{"isadmin", user.IsAdmin},
-		}},
+	if err = database.DeleteRecord(database.USERS_TABLE_NAME, queryUser); err != nil {
+		return models.User{}, err
 	}
-	var userupdate models.User
-
-	errN := collection.FindOneAndUpdate(ctx, filter, update).Decode(&userupdate)
-	if errN != nil {
-		fmt.Println("Could not update: ")
-		fmt.Println(errN)
-	} else {
-		fmt.Println("User updated  successfully.")
+	data, err := json.Marshal(&user)
+	if err != nil {
+		return models.User{}, err
 	}
-
-	defer cancel()
-
-	return user, errN
+	if err = database.Insert(user.UserName, string(data), database.USERS_TABLE_NAME); err != nil {
+		return models.User{}, err
+	}
+	functions.PrintUserLog("netmaker", "updated user "+queryUser, 1)
+	return user, nil
 }
 
 func updateUser(w http.ResponseWriter, r *http.Request) {
@@ -496,25 +445,11 @@ func updateUserAdm(w http.ResponseWriter, r *http.Request) {
 
 func DeleteUser(user string) (bool, error) {
 
-	deleted := false
-
-	collection := mongoconn.Client.Database("netmaker").Collection("users")
-
-	filter := bson.M{"username": user}
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	result, err := collection.DeleteOne(ctx, filter)
-
-	deletecount := result.DeletedCount
-
-	if deletecount > 0 {
-		deleted = true
+	err := database.DeleteRecord(database.USERS_TABLE_NAME, user)
+	if err != nil {
+		return false, err
 	}
-
-	defer cancel()
-
-	return deleted, err
+	return true, nil
 }
 
 func deleteUser(w http.ResponseWriter, r *http.Request) {

+ 8 - 12
controllers/userHttpController_test.go

@@ -1,23 +1,19 @@
 package controller
 
 import (
-	"context"
-	"os"
 	"testing"
-	"time"
 
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
 	"github.com/stretchr/testify/assert"
 )
 
-func TestMain(m *testing.M) {
-	mongoconn.ConnectDatabase()
+/*func TestMain(m *testing.M) {
+	database.InitializeDatabase()
 	var gconf models.GlobalConfig
 	gconf.ServerGRPC = "localhost:8081"
 	gconf.PortGRPC = "50051"
 	//err := SetGlobalConfig(gconf)
-	collection := mongoconn.Client.Database("netmaker").Collection("config")
+	collection := REMOVE.Client.Database("netmaker").Collection("config")
 	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 	defer cancel()
 	//create, _, err := functions.GetGlobalConfig()
@@ -28,7 +24,7 @@ func TestMain(m *testing.M) {
 	//drop network, nodes, and user collections
 	var collections = []string{"networks", "nodes", "users", "dns"}
 	for _, table := range collections {
-		collection := mongoconn.Client.Database("netmaker").Collection(table)
+		collection := REMOVE.Client.Database("netmaker").Collection(table)
 		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
 		defer cancel()
 		err := collection.Drop(ctx)
@@ -38,7 +34,7 @@ func TestMain(m *testing.M) {
 	}
 	os.Exit(m.Run())
 }
-
+*/
 func TestHasAdmin(t *testing.T) {
 	_, err := DeleteUser("admin")
 	assert.Nil(t, err)
@@ -179,12 +175,12 @@ func TestUpdateUser(t *testing.T) {
 
 func TestValidateUserToken(t *testing.T) {
 	t.Run("EmptyToken", func(t *testing.T) {
-		err := ValidateUserToken("","",false)
+		err := ValidateUserToken("", "", false)
 		assert.NotNil(t, err)
 		assert.Equal(t, "Missing Auth Token.", err.Error())
 	})
 	t.Run("InvalidToken", func(t *testing.T) {
-		err := ValidateUserToken("Bearer: badtoken","",false)
+		err := ValidateUserToken("Bearer: badtoken", "", false)
 		assert.NotNil(t, err)
 		assert.Equal(t, "Error Verifying Auth Token", err.Error())
 	})
@@ -193,7 +189,7 @@ func TestValidateUserToken(t *testing.T) {
 		//need authorization
 	})
 	t.Run("ValidToken", func(t *testing.T) {
-		err := ValidateUserToken("Bearer: secretkey","",true)
+		err := ValidateUserToken("Bearer: secretkey", "", true)
 		assert.Nil(t, err)
 	})
 }

+ 0 - 3
database/database.go

@@ -1,8 +1,6 @@
 package database
 
 import (
-	"log"
-
 	"github.com/rqlite/gorqlite"
 )
 
@@ -95,6 +93,5 @@ func FetchRecords(tableName string) (map[string]string, error) {
 		row.Scan(&key, &value)
 		records[key] = value
 	}
-	log.Println(tableName, records)
 	return records, nil
 }

+ 32 - 2
functions/helpers.go

@@ -27,6 +27,30 @@ func PrintUserLog(username string, message string, loglevel int) {
 	}
 }
 
+func ParseNetwork(value string) (models.Network, error) {
+	var network models.Network
+	err := json.Unmarshal([]byte(value), &network)
+	return network, err
+}
+
+func ParseNode(value string) (models.Node, error) {
+	var node models.Node
+	err := json.Unmarshal([]byte(value), &node)
+	return node, err
+}
+
+func ParseExtClient(value string) (models.ExtClient, error) {
+	var extClient models.ExtClient
+	err := json.Unmarshal([]byte(value), &extClient)
+	return extClient, err
+}
+
+func ParseIntClient(value string) (models.IntClient, error) {
+	var intClient models.IntClient
+	err := json.Unmarshal([]byte(value), &intClient)
+	return intClient, err
+}
+
 //Takes in an arbitrary field and value for field and checks to see if any other
 //node has that value for the same field within the network
 
@@ -151,6 +175,12 @@ func NetworkExists(name string) (bool, error) {
 	}
 	return len(network) > 0, nil
 }
+func GetRecordKey(id string, network string) (string, error) {
+	if id == "" || network == "" {
+		return "", errors.New("unable to get record key")
+	}
+	return id + "###" + network, nil
+}
 
 //TODO: This is  very inefficient (N-squared). Need to find a better way.
 //Takes a list of  nodes in a network and iterates through
@@ -391,8 +421,8 @@ func GetParentNetwork(networkname string) (models.Network, error) {
 	if err != nil {
 		return network, err
 	}
-	if err = json.Unmarshal([]byte(networkData), network); err != nil {
-		return network, err
+	if err = json.Unmarshal([]byte(networkData), &network); err != nil {
+		return models.Network{}, err
 	}
 	return network, nil
 }

+ 1 - 7
main.go

@@ -4,7 +4,6 @@
 package main
 
 import (
-	"context"
 	"log"
 	"net"
 	"os"
@@ -17,7 +16,6 @@ import (
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/functions"
 	nodepb "github.com/gravitl/netmaker/grpc"
-	"github.com/gravitl/netmaker/mongoconn"
 	"github.com/gravitl/netmaker/servercfg"
 	"github.com/gravitl/netmaker/serverctl"
 	"google.golang.org/grpc"
@@ -133,8 +131,6 @@ func runGRPC(wg *sync.WaitGroup) {
 	// Register the service with the server
 	nodepb.RegisterNodeServiceServer(s, srv)
 
-	srv.NodeDB = mongoconn.NodeDB
-
 	// Start the server in a child routine
 	go func() {
 		if err := s.Serve(listener); err != nil {
@@ -160,9 +156,7 @@ func runGRPC(wg *sync.WaitGroup) {
 	s.Stop()
 	listener.Close()
 	log.Println("Agent server closed..")
-	log.Println("Closing MongoDB connection")
-	mongoconn.Client.Disconnect(context.TODO())
-	log.Println("MongoDB connection closed.")
+	log.Println("Closed DB connection.")
 }
 
 func authServerUnaryInterceptor() grpc.ServerOption {

+ 13 - 14
models/network.go

@@ -1,7 +1,6 @@
 package models
 
 import (
-	//  "../mongoconn"
 	"time"
 
 	"go.mongodb.org/mongo-driver/bson/primitive"
@@ -22,7 +21,7 @@ type Network struct {
 	NetworkLastModified int64       `json:"networklastmodified" bson:"networklastmodified"`
 	DefaultInterface    string      `json:"defaultinterface" bson:"defaultinterface"`
 	DefaultListenPort   int32       `json:"defaultlistenport,omitempty" bson:"defaultlistenport,omitempty" validate:"omitempty,min=1024,max=65535"`
-	NodeLimit	    int32       `json:"nodelimit" bson:"nodelimit"`
+	NodeLimit           int32       `json:"nodelimit" bson:"nodelimit"`
 	DefaultPostUp       string      `json:"defaultpostup" bson:"defaultpostup"`
 	DefaultPostDown     string      `json:"defaultpostdown" bson:"defaultpostdown"`
 	KeyUpdateTimeStamp  int64       `json:"keyupdatetimestamp" bson:"keyupdatetimestamp"`
@@ -32,9 +31,9 @@ type Network struct {
 	AllowManualSignUp   *bool       `json:"allowmanualsignup" bson:"allowmanualsignup"`
 	IsLocal             *bool       `json:"islocal" bson:"islocal"`
 	IsDualStack         *bool       `json:"isdualstack" bson:"isdualstack"`
-	IsIPv4         string       `json:"isipv4" bson:"isipv4"`
-	IsIPv6         string       `json:"isipv6" bson:"isipv6"`
-	IsGRPCHub         string       `json:"isgrpchub" bson:"isgrpchub"`
+	IsIPv4              string      `json:"isipv4" bson:"isipv4"`
+	IsIPv6              string      `json:"isipv6" bson:"isipv6"`
+	IsGRPCHub           string      `json:"isgrpchub" bson:"isgrpchub"`
 	LocalRange          string      `json:"localrange" bson:"localrange" validate:"omitempty,cidr"`
 	//can't have min=1 with omitempty
 	DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"`
@@ -53,7 +52,7 @@ type NetworkUpdate struct {
 	NetworkLastModified int64       `json:"networklastmodified" bson:"networklastmodified"`
 	DefaultInterface    string      `json:"defaultinterface" bson:"defaultinterface"`
 	DefaultListenPort   int32       `json:"defaultlistenport,omitempty" bson:"defaultlistenport,omitempty" validate:"omitempty,min=1024,max=65535"`
-	NodeLimit	    int32       `json:"nodelimit" bson:"nodelimit"`
+	NodeLimit           int32       `json:"nodelimit" bson:"nodelimit"`
 	DefaultPostUp       string      `json:"defaultpostup" bson:"defaultpostup"`
 	DefaultPostDown     string      `json:"defaultpostdown" bson:"defaultpostdown"`
 	KeyUpdateTimeStamp  int64       `json:"keyupdatetimestamp" bson:"keyupdatetimestamp"`
@@ -63,9 +62,9 @@ type NetworkUpdate struct {
 	AllowManualSignUp   *bool       `json:"allowmanualsignup" bson:"allowmanualsignup"`
 	IsLocal             *bool       `json:"islocal" bson:"islocal"`
 	IsDualStack         *bool       `json:"isdualstack" bson:"isdualstack"`
-        IsIPv4         string       `json:"isipv4" bson:"isipv4"`
-        IsIPv6         string       `json:"isipv6" bson:"isipv6"`
-        IsGRPCHub         string       `json:"isgrpchub" bson:"isgrpchub"`
+	IsIPv4              string      `json:"isipv4" bson:"isipv4"`
+	IsIPv6              string      `json:"isipv6" bson:"isipv6"`
+	IsGRPCHub           string      `json:"isgrpchub" bson:"isgrpchub"`
 	LocalRange          string      `json:"localrange" bson:"localrange" validate:"omitempty,cidr"`
 	//can't have min=1 with omitempty
 	DefaultCheckInInterval int32 `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"`
@@ -95,9 +94,9 @@ func (network *Network) SetDefaults() {
 	if network.DefaultListenPort == 0 {
 		network.DefaultListenPort = 51821
 	}
-        if network.NodeLimit == 0 {
-                network.NodeLimit = 999999999
-        }
+	if network.NodeLimit == 0 {
+		network.NodeLimit = 999999999
+	}
 	if network.DefaultPostDown == "" {
 
 	}
@@ -122,7 +121,7 @@ func (network *Network) SetDefaults() {
 		network.IsIPv6 = "yes"
 		network.IsIPv4 = "yes"
 	} else if network.IsGRPCHub != "yes" {
-                network.IsIPv6 = "no"
-                network.IsIPv4 = "yes"
+		network.IsIPv6 = "no"
+		network.IsIPv4 = "yes"
 	}
 }

+ 32 - 67
models/node.go

@@ -1,13 +1,12 @@
 package models
 
 import (
-	"context"
+	"encoding/json"
 	"math/rand"
 	"net"
 	"time"
 
-	"github.com/gravitl/netmaker/mongoconn"
-	"go.mongodb.org/mongo-driver/bson"
+	"github.com/gravitl/netmaker/database"
 	"go.mongodb.org/mongo-driver/bson/primitive"
 )
 
@@ -28,7 +27,7 @@ type Node struct {
 	Endpoint            string             `json:"endpoint" bson:"endpoint" validate:"required,ip"`
 	PostUp              string             `json:"postup" bson:"postup"`
 	PostDown            string             `json:"postdown" bson:"postdown"`
-	AllowedIPs          []string             `json:"allowedips" bson:"allowedips"`
+	AllowedIPs          []string           `json:"allowedips" bson:"allowedips"`
 	PersistentKeepalive int32              `json:"persistentkeepalive" bson:"persistentkeepalive" validate:"omitempty,numeric,max=1000"`
 	SaveConfig          *bool              `json:"saveconfig" bson:"saveconfig"`
 	AccessKey           string             `json:"accesskey" bson:"accesskey"`
@@ -43,13 +42,13 @@ type Node struct {
 	Password            string             `json:"password" bson:"password" validate:"required,min=6"`
 	Network             string             `json:"network" bson:"network" validate:"network_exists"`
 	IsPending           bool               `json:"ispending" bson:"ispending"`
-	IsEgressGateway           bool               `json:"isegressgateway" bson:"isegressgateway"`
-	IsIngressGateway           bool               `json:"isingressgateway" bson:"isingressgateway"`
-	EgressGatewayRanges        []string             `json:"egressgatewayranges" bson:"egressgatewayranges"`
-	IngressGatewayRange        string             `json:"ingressgatewayrange" bson:"ingressgatewayrange"`
+	IsEgressGateway     bool               `json:"isegressgateway" bson:"isegressgateway"`
+	IsIngressGateway    bool               `json:"isingressgateway" bson:"isingressgateway"`
+	EgressGatewayRanges []string           `json:"egressgatewayranges" bson:"egressgatewayranges"`
+	IngressGatewayRange string             `json:"ingressgatewayrange" bson:"ingressgatewayrange"`
 	PostChanges         string             `json:"postchanges" bson:"postchanges"`
-        StaticIP         string             `json:"staticip" bson:"staticip"`
-        StaticPubKey         string             `json:"staticpubkey" bson:"staticpubkey"`
+	StaticIP            string             `json:"staticip" bson:"staticip"`
+	StaticPubKey        string             `json:"staticpubkey" bson:"staticpubkey"`
 }
 
 //node update struct --- only validations are different
@@ -64,7 +63,7 @@ type NodeUpdate struct {
 	Endpoint            string             `json:"endpoint" bson:"endpoint" validate:"omitempty,ip"`
 	PostUp              string             `json:"postup" bson:"postup"`
 	PostDown            string             `json:"postdown" bson:"postdown"`
-	AllowedIPs          []string             `json:"allowedips" bson:"allowedips"`
+	AllowedIPs          []string           `json:"allowedips" bson:"allowedips"`
 	PersistentKeepalive int32              `json:"persistentkeepalive" bson:"persistentkeepalive" validate:"omitempty,numeric,max=1000"`
 	SaveConfig          *bool              `json:"saveconfig" bson:"saveconfig"`
 	AccessKey           string             `json:"accesskey" bson:"accesskey"`
@@ -79,60 +78,13 @@ type NodeUpdate struct {
 	Password            string             `json:"password" bson:"password" validate:"omitempty,min=5"`
 	Network             string             `json:"network" bson:"network" validate:"network_exists"`
 	IsPending           bool               `json:"ispending" bson:"ispending"`
-	IsIngressGateway           bool               `json:"isingressgateway" bson:"isingressgateway"`
-	IsEgressGateway           bool               `json:"isegressgateway" bson:"isegressgateway"`
-        IngressGatewayRange        string             `json:"ingressgatewayrange" bson:"ingressgatewayrange"`
-	EgressGatewayRanges        []string             `json:"egressgatewayranges" bson:"egressgatewayranges"`
+	IsIngressGateway    bool               `json:"isingressgateway" bson:"isingressgateway"`
+	IsEgressGateway     bool               `json:"isegressgateway" bson:"isegressgateway"`
+	IngressGatewayRange string             `json:"ingressgatewayrange" bson:"ingressgatewayrange"`
+	EgressGatewayRanges []string           `json:"egressgatewayranges" bson:"egressgatewayranges"`
 	PostChanges         string             `json:"postchanges" bson:"postchanges"`
-	StaticIP         string             `json:"staticip" bson:"staticip"`
-	StaticPubKey         string             `json:"staticpubkey" bson:"staticpubkey"`
-}
-
-//Duplicated function for NodeUpdates
-func (node *NodeUpdate) GetNetwork() (Network, error) {
-
-	var network Network
-
-	collection := mongoconn.NetworkDB
-	//collection := mongoconn.Client.Database("netmaker").Collection("networks")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	filter := bson.M{"netid": node.Network}
-	err := collection.FindOne(ctx, filter).Decode(&network)
-
-	defer cancel()
-
-	if err != nil {
-		//log.Fatal(err)
-		return network, err
-	}
-
-	return network, err
-}
-
-//TODO: Contains a fatal error return. Need to change
-//Used in contexts where it's not the Parent network.
-func (node *Node) GetNetwork() (Network, error) {
-
-	var network Network
-
-	//collection := mongoconn.NetworkDB
-	collection := mongoconn.Client.Database("netmaker").Collection("networks")
-
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-
-	filter := bson.M{"netid": node.Network}
-	err := collection.FindOne(ctx, filter).Decode(&network)
-
-	defer cancel()
-
-	if err != nil {
-		//log.Fatal(err)
-		return network, err
-	}
-
-	return network, err
+	StaticIP            string             `json:"staticip" bson:"staticip"`
+	StaticPubKey        string             `json:"staticpubkey" bson:"staticpubkey"`
 }
 
 //TODO:
@@ -161,6 +113,19 @@ func (node *Node) SetDefaultName() {
 	}
 }
 
+func (node *Node) GetNetwork() (Network, error) {
+
+	var network Network
+	networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, node.Network)
+	if err != nil {
+		return network, err
+	}
+	if err = json.Unmarshal([]byte(networkData), &network); err != nil {
+		return Network{}, err
+	}
+	return network, nil
+}
+
 //TODO: I dont know why this exists
 //This should exist on the node.go struct. I'm sure there was a reason?
 func (node *Node) SetDefaults() {
@@ -198,9 +163,9 @@ func (node *Node) SetDefaults() {
 	if node.StaticIP == "" {
 		node.StaticIP = "no"
 	}
-        if node.StaticPubKey == "" {
-                node.StaticPubKey = "no"
-        }
+	if node.StaticPubKey == "" {
+		node.StaticPubKey = "no"
+	}
 
 	node.CheckInInterval = parentNetwork.DefaultCheckInInterval
 

+ 0 - 67
mongoconn/mongoconn.go

@@ -1,67 +0,0 @@
-package mongoconn
-
-import (
-	"context"
-	"log"
-	"go.mongodb.org/mongo-driver/mongo"
-	"go.mongodb.org/mongo-driver/mongo/options"
-        "github.com/gravitl/netmaker/servercfg"
-)
-
-var Client *mongo.Client
-var NodeDB *mongo.Collection
-var NetworkDB *mongo.Collection
-var user string
-var pass string
-var host string
-var port string
-var opts string
-
-func setVars() {
-	user = servercfg.GetMongoUser()
-	pass = servercfg.GetMongoPass()
-	host = servercfg.GetMongoHost()
-	port = servercfg.GetMongoPort()
-	opts = servercfg.GetMongoOpts()
-}
-
-func ConnectDatabase() {
-    // Set client options
-
-    setVars()
-
-    clientOptions := options.Client().ApplyURI( "mongodb://" +
-						user + ":" +
-						pass + "@" +
-						host + ":" +
-						port +
-						opts )
-
-    // Connect to MongoDB
-    log.Println("Connecting to MongoDB at " + host + ":" + port + "...")
-    client, err := mongo.Connect(context.TODO(), clientOptions)
-    Client = client
-    if err != nil {
-	log.Println("Error encountered connecting to MongoDB. Terminating.")
-        log.Fatal(err)
-    }
-
-    // Check the connection
-    err = Client.Ping(context.TODO(), nil)
-
-    if err != nil {
-	log.Println("Error encountered pinging MongoDB. Terminating.")
-        log.Fatal(err)
-    }
-
-    NodeDB = Client.Database("netmaker").Collection("nodes")
-    NetworkDB = Client.Database("netmaker").Collection("networks")
-
-    log.Println("MongoDB Connected.")
-}
-
-// ErrorResponse : This is error model.
-type ErrorResponse struct {
-	StatusCode   int    `json:"status"`
-	ErrorMessage string `json:"message"`
-}

+ 0 - 53
servercfg/mongoconf.go

@@ -1,53 +0,0 @@
-package servercfg
-
-import (
-        "github.com/gravitl/netmaker/config"
-        "os"
-)
-
-func GetMongoUser() string {
-	user := "mongoadmin"
-	if os.Getenv("MONGO_ADMIN") != "" {
-		user = os.Getenv("MONGO_ADMIN")
-	} else if  config.Config.MongoConn.User != "" {
-		user = config.Config.MongoConn.User
-	}
-	return user
-}
-func GetMongoPass() string {
-        pass := "mongopass"
-        if os.Getenv("MONGO_PASS") != "" {
-                pass = os.Getenv("MONGO_PASS")
-        } else if  config.Config.MongoConn.Pass != "" {
-                pass = config.Config.MongoConn.Pass
-        }
-        return pass
-}
-func GetMongoHost() string {
-        host := "127.0.0.1"
-        if os.Getenv("MONGO_HOST") != "" {
-                host = os.Getenv("MONGO_HOST")
-        } else if  config.Config.MongoConn.Host != "" {
-                host = config.Config.MongoConn.Host
-        }
-        return host
-}
-func GetMongoPort() string {
-        port := "27017"
-        if os.Getenv("MONGO_PORT") != "" {
-                port = os.Getenv("MONGO_PORT")
-        } else if  config.Config.MongoConn.Port != "" {
-                port = config.Config.MongoConn.Port
-        }
-        return port
-}
-func GetMongoOpts() string {
-        opts := "/?authSource=admin"
-        if os.Getenv("MONGO_OPTS") != "" {
-                opts = os.Getenv("MONGO_OPTS")
-        } else if  config.Config.MongoConn.Opts != "" {
-                opts = config.Config.MongoConn.Opts
-        }
-        return opts
-}
-

+ 11 - 11
serverctl/serverctl.go

@@ -1,7 +1,6 @@
 package serverctl
 
 import (
-	"context"
 	"encoding/json"
 	"errors"
 	"io"
@@ -13,21 +12,22 @@ import (
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/functions"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
 	"github.com/gravitl/netmaker/servercfg"
-	"go.mongodb.org/mongo-driver/bson"
-	"go.mongodb.org/mongo-driver/mongo/options"
 )
 
 func GetServerWGConf() (models.IntClient, error) {
 	var server models.IntClient
-	collection := mongoconn.Client.Database("netmaker").Collection("intclients")
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	filter := bson.M{"network": "comms", "isserver": "yes"}
-	err := collection.FindOne(ctx, filter, options.FindOne().SetProjection(bson.M{"_id": 0})).Decode(&server)
-	defer cancel()
-
-	return server, err
+	collection, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
+	if err != nil {
+		return models.IntClient{}, errors.New("could not find comms server")
+	}
+	for _, value := range collection {
+		json.Unmarshal([]byte(value), &server)
+		if server.Network == "comms" && server.IsServer == "yes" {
+			return server, nil
+		}
+	}
+	return models.IntClient{}, errors.New("could not find comms server")
 }
 
 func CreateCommsNetwork() (bool, error) {

+ 1 - 1
test/api_test.go

@@ -12,7 +12,7 @@ import (
 
 	controller "github.com/gravitl/netmaker/controllers"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/mongoconn"
+	""
 	"github.com/stretchr/testify/assert"
 )
 

+ 2 - 2
test/nodecreate.sh

@@ -3,7 +3,7 @@
 PUBKEY="DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34="
 IPADDR="69.173.21.202"
 MACADDRESS="59:2a:9c:d4:e2:49"
-ACCESSKEY="9ktiHcUWay2MSKsY"
+ACCESSKEY="I6Pc8UFlszO1MWh3"
 PASSWORD="ppppppp"
 
 generate_post_json ()
@@ -22,5 +22,5 @@ EOF
 
 POST_JSON=$(generate_post_json)
 
-curl --max-time 5.0 -d "$POST_JSON" -H 'Content-Type: application/json' -H "authorization: Bearer secretkey" localhost:8081/api/nodes/default
+curl --max-time 5.0 -d "$POST_JSON" -H 'Content-Type: application/json' -H "authorization: Bearer secretkey" localhost:8081/api/nodes/hello