Browse Source

Merge branch 'gravitl:develop' into develop

Adrien Raffin-Caboisse 3 years ago
parent
commit
3a399aff23
59 changed files with 801 additions and 221 deletions
  1. 10 0
      .github/dependabot.yml
  2. 3 2
      .github/workflows/publish-docker.yml
  3. 56 0
      compose/docker-compose.nodns.yml
  4. 15 2
      config/config.go
  5. 1 1
      controllers/authGrpc.go
  6. 4 2
      controllers/controller.go
  7. 11 3
      controllers/dnsHttpController.go
  8. 7 3
      controllers/extClientHttpController.go
  9. 2 3
      controllers/fileHttpController.go
  10. 13 13
      controllers/networkHttpController_test.go
  11. 8 5
      controllers/nodeGrpcController.go
  12. 3 2
      controllers/nodeHttpController.go
  13. 5 0
      controllers/relay.go
  14. 1 1
      controllers/serverHttpController.go
  15. 39 29
      controllers/userHttpController.go
  16. 5 3
      database/database.go
  17. 131 0
      database/postgres.go
  18. 4 4
      database/rqlite.go
  19. 5 5
      database/sqlite.go
  20. 5 0
      database/statics.go
  21. 4 0
      dnslogic/dns.go
  22. 16 0
      docker/Dockerfile-userspace
  23. 23 0
      docker/Dockerfile-wg-quick
  24. 50 3
      functions/helpers.go
  25. 3 1
      functions/jwt.go
  26. 25 25
      functions/local.go
  27. 1 0
      go.mod
  28. 2 0
      go.sum
  29. 1 0
      logic/extpeers.go
  30. 4 0
      logic/nodes.go
  31. 11 4
      logic/util.go
  32. 1 0
      logic/wireguard.go
  33. 1 1
      main.go
  34. 17 17
      models/accessToken.go
  35. 2 4
      models/extclient.go
  36. 14 14
      models/intclient.go
  37. 46 37
      models/network.go
  38. 5 5
      models/node.go
  39. 16 0
      models/structs.go
  40. 2 0
      models/validation.go
  41. 5 1
      netclient/auth/auth.go
  42. 20 9
      netclient/config/config.go
  43. 3 3
      netclient/daemon/macos.go
  44. 3 2
      netclient/daemon/systemd.go
  45. 5 0
      netclient/daemon/windows.go
  46. 3 4
      netclient/functions/checkin.go
  47. 8 0
      netclient/functions/common.go
  48. 1 0
      netclient/functions/join.go
  49. 2 0
      netclient/local/dns.go
  50. 10 3
      netclient/local/local.go
  51. 38 3
      netclient/ncutils/netclientutils.go
  52. 1 1
      netclient/ncwindows/windows.go
  53. 6 1
      netclient/server/grpc.go
  54. 5 1
      netclient/wireguard/common.go
  55. 5 1
      netclient/wireguard/unix.go
  56. 1 0
      relay/relay.go
  57. 31 3
      servercfg/serverconf.go
  58. 73 0
      servercfg/sqlconf.go
  59. 9 0
      serverctl/serverctl.go

+ 10 - 0
.github/dependabot.yml

@@ -0,0 +1,10 @@
+# Basic dependabot.yml file with minimum configuration for gomod.
+
+version: 2
+updates:
+  # Enable version updates for go
+  - package-ecosystem: "gomod"
+    directory: "/"
+    # Check for updates every day (weekdays)
+    schedule:
+      interval: "daily"

+ 3 - 2
.github/workflows/publish-docker.yml

@@ -31,7 +31,8 @@ jobs:
         uses: docker/setup-qemu-action@v1
       - name: Set up Docker Buildx
         uses: docker/setup-buildx-action@v1
-      - name: Login to DockerHub
+      - if: github.event_name != 'pull_request'
+        name: Login to DockerHub
         uses: docker/login-action@v1
         with:
           username: ${{ secrets.DOCKERHUB_USERNAME }}
@@ -41,5 +42,5 @@ jobs:
         with:
           context: .
           platforms: linux/amd64, linux/arm64
-          push: true
+          push: ${{ github.event_name != 'pull_request' }}
           tags: gravitl/netmaker:${{ env.TAG }}

+ 56 - 0
compose/docker-compose.nodns.yml

@@ -0,0 +1,56 @@
+version: "3.4"
+
+services:
+  netmaker:
+    container_name: netmaker
+    image: gravitl/netmaker:v0.8.3
+    volumes:
+      - /etc/netclient/config:/etc/netclient/config
+      - /usr/bin/wg:/usr/bin/wg
+      - sqldata:/root/data
+    cap_add: 
+      - NET_ADMIN
+    restart: always
+    network_mode: host
+    environment:
+      SERVER_HOST: "SERVER_PUBLIC_IP"
+      SERVER_API_CONN_STRING: "api.NETMAKER_BASE_DOMAIN:443"
+      SERVER_GRPC_CONN_STRING: "grpc.NETMAKER_BASE_DOMAIN:443"
+      COREDNS_ADDR: "SERVER_PUBLIC_IP"
+      GRPC_SSL: "on"
+      DNS_MODE: "off"
+      SERVER_HTTP_HOST: "api.NETMAKER_BASE_DOMAIN"
+      SERVER_GRPC_HOST: "grpc.NETMAKER_BASE_DOMAIN"
+      API_PORT: "8081"
+      GRPC_PORT: "50051"
+      CLIENT_MODE: "on"
+      MASTER_KEY: "REPLACE_MASTER_KEY"
+      SERVER_GRPC_WIREGUARD: "off"
+      CORS_ALLOWED_ORIGIN: "*"
+      DATABASE: "sqlite"
+  netmaker-ui:
+    container_name: netmaker-ui
+    depends_on:
+      - netmaker
+    image: gravitl/netmaker-ui:v0.8
+    links:
+      - "netmaker:api"
+    ports:
+      - "8082:80"
+    environment:
+      BACKEND_URL: "https://api.NETMAKER_BASE_DOMAIN"
+    restart: always
+  caddy:
+    image: caddy:latest
+    container_name: caddy
+    restart: unless-stopped
+    network_mode: host # Wants ports 80 and 443!
+    volumes:
+      - /root/Caddyfile:/etc/caddy/Caddyfile
+      # - $PWD/site:/srv # you could also serve a static site in site folder
+      - caddy_data:/data
+      - caddy_conf:/config
+volumes:
+  caddy_data: {}
+  caddy_conf: {}
+  sqldata: {}

+ 15 - 2
config/config.go

@@ -30,6 +30,7 @@ var Config *EnvironmentConfig
 // EnvironmentConfig :
 type EnvironmentConfig struct {
 	Server ServerConfig `yaml:"server"`
+	SQL SQLConfig `yaml:"sql"`
 }
 
 // ServerConfig :
@@ -44,23 +45,35 @@ type ServerConfig struct {
 	GRPCSecure           string `yaml:"grpcsecure"`
 	MasterKey            string `yaml:"masterkey"`
 	AllowedOrigin        string `yaml:"allowedorigin"`
+	NodeID        string `yaml:"nodeid"`
 	RestBackend          string `yaml:"restbackend"`
 	AgentBackend         string `yaml:"agentbackend"`
 	ClientMode           string `yaml:"clientmode"`
 	DNSMode              string `yaml:"dnsmode"`
-	SplitDNS           string `yaml:"splitdns"`
+	SplitDNS             string `yaml:"splitdns"`
 	DisableRemoteIPCheck string `yaml:"disableremoteipcheck"`
 	DisableDefaultNet    string `yaml:"disabledefaultnet"`
 	GRPCSSL              string `yaml:"grpcssl"`
 	Version              string `yaml:"version"`
 	SQLConn              string `yaml:"sqlconn"`
-	Platform              string `yaml:"platform"`
+	Platform             string `yaml:"platform"`
 	Database             string `yaml:database`
 	CheckinInterval      string `yaml:checkininterval`
 	DefaultNodeLimit     int32  `yaml:"defaultnodelimit"`
 	Verbosity            int32  `yaml:"verbosity"`
 }
 
+
+// Generic SQL Config
+type SQLConfig struct {
+	Host string `yaml:"host"`
+	Port int32 `yaml:"port"`
+	Username string `yaml:"username"`
+	Password string `yaml:"password"`
+	DB string `yaml:"db"`
+	SSLMode string `yaml:"sslmode"`
+}
+
 //reading in the env file
 func readConfig() *EnvironmentConfig {
 	file := fmt.Sprintf("config/environments/%s.yaml", getEnv())

+ 1 - 1
controllers/authGrpc.go

@@ -124,7 +124,7 @@ func (s *NodeServiceServer) Login(ctx context.Context, req *nodepb.Object) (*nod
 		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).
+		//Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API until approved).
 		collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
 		if err != nil {
 			return nil, err

+ 4 - 2
controllers/controller.go

@@ -7,11 +7,13 @@ import (
 	"os"
 	"os/signal"
 	"sync"
+
 	"github.com/gorilla/handlers"
 	"github.com/gorilla/mux"
 	"github.com/gravitl/netmaker/servercfg"
 )
 
+// HandleRESTRequests - handles the rest requests
 func HandleRESTRequests(wg *sync.WaitGroup) {
 	defer wg.Done()
 
@@ -30,7 +32,7 @@ func HandleRESTRequests(wg *sync.WaitGroup) {
 	fileHandlers(r)
 	serverHandlers(r)
 	extClientHandlers(r)
-	
+
 	port := servercfg.GetAPIPort()
 
 	srv := &http.Server{Addr: ":" + port, Handler: handlers.CORS(originsOk, headersOk, methodsOk)(r)}
@@ -41,7 +43,7 @@ func HandleRESTRequests(wg *sync.WaitGroup) {
 		}
 	}()
 
-	log.Println("REST Server succesfully started on port " + port + " (REST)")
+	log.Println("REST Server successfully started on port " + port + " (REST)")
 	c := make(chan os.Signal)
 
 	// Relay os.Interrupt to our channel (os.Interrupt = CTRL+C)

+ 11 - 3
controllers/dnsHttpController.go

@@ -56,6 +56,7 @@ func getAllDNS(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(dns)
 }
 
+// GetAllDNS - gets all dns entries
 func GetAllDNS() ([]models.DNSEntry, error) {
 	var dns []models.DNSEntry
 	networks, err := models.GetNetworks()
@@ -72,6 +73,7 @@ func GetAllDNS() ([]models.DNSEntry, error) {
 	return dns, nil
 }
 
+// GetNodeDNS - gets node dns
 func GetNodeDNS(network string) ([]models.DNSEntry, error) {
 
 	var dns []models.DNSEntry
@@ -114,6 +116,7 @@ func getCustomDNS(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(dns)
 }
 
+// GetDNSEntryNum - gets which entry the dns was
 func GetDNSEntryNum(domain string, network string) (int, error) {
 
 	num := 0
@@ -133,7 +136,7 @@ func GetDNSEntryNum(domain string, network string) (int, error) {
 	return num, nil
 }
 
-//Gets all nodes associated with network, including pending nodes
+// Gets all nodes associated with network, including pending nodes
 func getDNS(w http.ResponseWriter, r *http.Request) {
 
 	w.Header().Set("Content-Type", "application/json")
@@ -202,7 +205,7 @@ func updateDNS(w http.ResponseWriter, r *http.Request) {
 		returnErrorResponse(w, r, formatError(err, "badrequest"))
 		return
 	}
-	//fill in any missing fields
+	// fill in any missing fields
 	if dnschange.Name == "" {
 		dnschange.Name = entry.Name
 	}
@@ -257,6 +260,7 @@ func deleteDNS(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(entrytext + " deleted.")
 }
 
+// CreateDNS - creates a DNS entry
 func CreateDNS(entry models.DNSEntry) (models.DNSEntry, error) {
 
 	data, err := json.Marshal(&entry)
@@ -272,6 +276,7 @@ func CreateDNS(entry models.DNSEntry) (models.DNSEntry, error) {
 	return entry, err
 }
 
+// GetDNSEntry - gets a DNS entry
 func GetDNSEntry(domain string, network string) (models.DNSEntry, error) {
 	var entry models.DNSEntry
 	key, err := functions.GetRecordKey(domain, network)
@@ -286,6 +291,7 @@ func GetDNSEntry(domain string, network string) (models.DNSEntry, error) {
 	return entry, err
 }
 
+// UpdateDNS - updates DNS entry
 func UpdateDNS(dnschange models.DNSEntry, entry models.DNSEntry) (models.DNSEntry, error) {
 
 	key, err := functions.GetRecordKey(entry.Name, entry.Network)
@@ -308,9 +314,9 @@ func UpdateDNS(dnschange models.DNSEntry, entry models.DNSEntry) (models.DNSEntr
 	data, err := json.Marshal(&entry)
 	err = database.Insert(newkey, string(data), database.DNS_TABLE_NAME)
 	return entry, err
-
 }
 
+// DeleteDNS - deletes a DNS entry
 func DeleteDNS(domain string, network string) error {
 	key, err := functions.GetRecordKey(domain, network)
 	if err != nil {
@@ -334,6 +340,7 @@ func pushDNS(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode("DNS Pushed to CoreDNS")
 }
 
+// ValidateDNSCreate - checks if an entry is valid
 func ValidateDNSCreate(entry models.DNSEntry) error {
 
 	v := validator.New()
@@ -357,6 +364,7 @@ func ValidateDNSCreate(entry models.DNSEntry) error {
 	return err
 }
 
+// ValidateDNSUpdate - validates a DNS update
 func ValidateDNSUpdate(change models.DNSEntry, entry models.DNSEntry) error {
 
 	v := validator.New()

+ 7 - 3
controllers/extClientHttpController.go

@@ -56,6 +56,7 @@ func getNetworkExtClients(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(extclients)
 }
 
+// GetNetworkExtClients - gets the ext clients of given network
 func GetNetworkExtClients(network string) ([]models.ExtClient, error) {
 	var extclients []models.ExtClient
 
@@ -130,6 +131,7 @@ func getExtClient(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(client)
 }
 
+// GetExtClient - gets a single ext client on a network
 func GetExtClient(clientid string, network string) (models.ExtClient, error) {
 	var extclient models.ExtClient
 	key, err := functions.GetRecordKey(clientid, network)
@@ -238,6 +240,7 @@ Endpoint = %s
 	json.NewEncoder(w).Encode(client)
 }
 
+// CreateExtClient - creates an extclient
 func CreateExtClient(extclient models.ExtClient) error {
 	if extclient.PrivateKey == "" {
 		privateKey, err := wgtypes.GeneratePrivateKey()
@@ -351,6 +354,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(newclient)
 }
 
+// UpdateExtClient - only supports name changes right now
 func UpdateExtClient(newclientid string, network string, client models.ExtClient) (models.ExtClient, error) {
 
 	err := DeleteExtClient(network, client.ClientID)
@@ -362,6 +366,7 @@ func UpdateExtClient(newclientid string, network string, client models.ExtClient
 	return client, err
 }
 
+// DeleteExtClient - deletes an existing ext client
 func DeleteExtClient(network string, clientid string) error {
 	key, err := functions.GetRecordKey(clientid, network)
 	if err != nil {
@@ -371,9 +376,7 @@ func DeleteExtClient(network string, clientid string) error {
 	return err
 }
 
-/**
- * Deletes ext clients based on gateway (mac) of ingress node and network
- */
+// DeleteGatewayExtClients - deletes ext clients based on gateway (mac) of ingress node and network
 func DeleteGatewayExtClients(gatewayID string, networkName string) error {
 	currentExtClients, err := GetNetworkExtClients(networkName)
 	if err != nil && !database.IsEmptyRecord(err) {
@@ -411,6 +414,7 @@ func deleteExtClient(w http.ResponseWriter, r *http.Request) {
 	returnSuccessResponse(w, r, params["clientid"]+" deleted.")
 }
 
+// StringWithCharset - returns a random string in a charset
 func StringWithCharset(length int, charset string) string {
 	b := make([]byte, length)
 	for i := range b {

+ 2 - 3
controllers/fileHttpController.go

@@ -1,11 +1,10 @@
 package controller
 
 import (
-    "net/http"
-    "github.com/gorilla/mux"
+	"github.com/gorilla/mux"
+	"net/http"
 )
 
-
 func fileHandlers(r *mux.Router) {
 	r.PathPrefix("/meshclient/files").Handler(http.StripPrefix("/meshclient/files", http.FileServer(http.Dir("./meshclient/files"))))
 }

+ 13 - 13
controllers/networkHttpController_test.go

@@ -228,14 +228,14 @@ func TestValidateNetworkUpdate(t *testing.T) {
 
 	//DeleteNetworks
 	cases := []NetworkValidationTestCase{
-		NetworkValidationTestCase{
+		{
 			testname: "InvalidAddress",
 			network: models.Network{
 				AddressRange: "10.0.0.256",
 			},
 			errMessage: "Field validation for 'AddressRange' failed on the 'cidr' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "InvalidAddress6",
 			network: models.Network{
 				AddressRange6: "2607::ag",
@@ -243,77 +243,77 @@ func TestValidateNetworkUpdate(t *testing.T) {
 			errMessage: "Field validation for 'AddressRange6' failed on the 'cidr' tag",
 		},
 
-		NetworkValidationTestCase{
+		{
 			testname: "BadDisplayName",
 			network: models.Network{
 				DisplayName: "skynet*",
 			},
 			errMessage: "Field validation for 'DisplayName' failed on the 'alphanum' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "DisplayNameTooLong",
 			network: models.Network{
 				DisplayName: "Thisisareallylongdisplaynamethatistoolong",
 			},
 			errMessage: "Field validation for 'DisplayName' failed on the 'max' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "DisplayNameTooShort",
 			network: models.Network{
 				DisplayName: "1",
 			},
 			errMessage: "Field validation for 'DisplayName' failed on the 'min' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "InvalidNetID",
 			network: models.Network{
 				NetID: "contains spaces",
 			},
 			errMessage: "Field validation for 'NetID' failed on the 'alphanum' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "NetIDTooLong",
 			network: models.Network{
 				NetID: "LongNetIDName",
 			},
 			errMessage: "Field validation for 'NetID' failed on the 'max' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "ListenPortTooLow",
 			network: models.Network{
 				DefaultListenPort: 1023,
 			},
 			errMessage: "Field validation for 'DefaultListenPort' failed on the 'min' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "ListenPortTooHigh",
 			network: models.Network{
 				DefaultListenPort: 65536,
 			},
 			errMessage: "Field validation for 'DefaultListenPort' failed on the 'max' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "KeepAliveTooBig",
 			network: models.Network{
 				DefaultKeepalive: 1010,
 			},
 			errMessage: "Field validation for 'DefaultKeepalive' failed on the 'max' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "InvalidLocalRange",
 			network: models.Network{
 				LocalRange: "192.168.0.1",
 			},
 			errMessage: "Field validation for 'LocalRange' failed on the 'cidr' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "CheckInIntervalTooBig",
 			network: models.Network{
 				DefaultCheckInInterval: 100001,
 			},
 			errMessage: "Field validation for 'DefaultCheckInInterval' failed on the 'max' tag",
 		},
-		NetworkValidationTestCase{
+		{
 			testname: "CheckInIntervalTooSmall",
 			network: models.Network{
 				DefaultCheckInInterval: 1,

+ 8 - 5
controllers/nodeGrpcController.go

@@ -12,10 +12,12 @@ import (
 	"github.com/gravitl/netmaker/models"
 )
 
+// NodeServiceServer - represents the service server for gRPC
 type NodeServiceServer struct {
 	nodepb.UnimplementedNodeServiceServer
 }
 
+// NodeServiceServer.ReadNode - reads node and responds with gRPC
 func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
 	// convert string id (from proto) to mongoDB ObjectId
 	macAndNetwork := strings.Split(req.Data, "###")
@@ -41,6 +43,7 @@ func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.Object) (*
 	return response, nil
 }
 
+// NodeServiceServer.CreateNode - creates a node and responds over gRPC
 func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
 	// Get the protobuf node type from the protobuf request type
 	// Essentially doing req.Node to access the struct with a nil check
@@ -86,6 +89,7 @@ func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object)
 	return response, nil
 }
 
+// NodeServiceServer.UpdateNode updates a node and responds over gRPC
 func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
 	// Get the node data from the request
 	var newnode models.Node
@@ -113,6 +117,7 @@ func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.Object)
 	}, nil
 }
 
+// NodeServiceServer.DeleteNode - deletes a node and responds over gRPC
 func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
 	nodeID := req.GetData()
 
@@ -127,6 +132,7 @@ func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.Object)
 	}, nil
 }
 
+// NodeServiceServer.GetPeers - fetches peers over gRPC
 func (s *NodeServiceServer) GetPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
 	macAndNetwork := strings.Split(req.Data, "###")
 	if len(macAndNetwork) == 2 {
@@ -135,7 +141,7 @@ func (s *NodeServiceServer) GetPeers(ctx context.Context, req *nodepb.Object) (*
 		if err != nil {
 			return nil, err
 		}
-		if node.IsServer == "yes" && logic.IsLeader(&node){
+		if node.IsServer == "yes" && logic.IsLeader(&node) {
 			logic.SetNetworkServerPeers(&node)
 		}
 		excludeIsRelayed := node.IsRelay != "yes"
@@ -161,10 +167,7 @@ func (s *NodeServiceServer) GetPeers(ctx context.Context, req *nodepb.Object) (*
 	}, errors.New("could not fetch peers, invalid node id")
 }
 
-/**
- * Return Ext Peers (clients).NodeCheckIn
- * When a gateway node checks in, it pulls these peers to add to peers list in addition to normal network peers.
- */
+// NodeServiceServer.GetExtPeers - returns ext peers for a gateway node
 func (s *NodeServiceServer) GetExtPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
 	// Initiate a NodeItem type to write decoded data to
 	//data := &models.PeersResponse{}

+ 3 - 2
controllers/nodeHttpController.go

@@ -6,6 +6,7 @@ import (
 	"net/http"
 	"strings"
 	"time"
+
 	"github.com/gorilla/mux"
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/dnslogic"
@@ -71,7 +72,7 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
 			return
 		} else {
 
-			//Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API untill approved).
+			//Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API until approved).
 			collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
 			if err != nil {
 				errorResponse.Code = http.StatusBadRequest
@@ -189,7 +190,7 @@ func authorize(networkCheck bool, authNetwork string, next http.Handler) http.Ha
 			//This checks if
 			//A: the token is the master password
 			//B: the token corresponds to a mac address, and if so, which one
-			//TODO: There's probably a better way of dealing with the "master token"/master password. Plz Halp.
+			//TODO: There's probably a better way of dealing with the "master token"/master password. Plz Help.
 			var isAuthorized = false
 			var macaddress = ""
 			username, networks, isadmin, errN := functions.VerifyUserToken(authToken)

+ 5 - 0
controllers/relay.go

@@ -33,6 +33,7 @@ func createRelay(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(node)
 }
 
+// CreateRelay - creates a relay
 func CreateRelay(relay models.RelayRequest) (models.Node, error) {
 	node, err := functions.GetNodeByMacAddress(relay.NetID, relay.NodeID)
 	if node.OS == "windows" || node.OS == "macos" { // add in darwin later
@@ -87,6 +88,7 @@ func deleteRelay(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(node)
 }
 
+// SetRelayedNodes- set relayed nodes
 func SetRelayedNodes(yesOrno string, networkName string, addrs []string) error {
 
 	collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
@@ -118,6 +120,7 @@ func SetRelayedNodes(yesOrno string, networkName string, addrs []string) error {
 	return nil
 }
 
+// ValidateRelay - checks if relay is valid
 func ValidateRelay(relay models.RelayRequest) error {
 	var err error
 	//isIp := functions.IsIpCIDR(gateway.RangeString)
@@ -128,6 +131,7 @@ func ValidateRelay(relay models.RelayRequest) error {
 	return err
 }
 
+// UpdateRelay - updates a relay
 func UpdateRelay(network string, oldAddrs []string, newAddrs []string) {
 	time.Sleep(time.Second / 4)
 	err := SetRelayedNodes("no", network, oldAddrs)
@@ -140,6 +144,7 @@ func UpdateRelay(network string, oldAddrs []string, newAddrs []string) {
 	}
 }
 
+// DeleteRelay - deletes a relay
 func DeleteRelay(network, macaddress string) (models.Node, error) {
 
 	node, err := functions.GetNodeByMacAddress(network, macaddress)

+ 1 - 1
controllers/serverHttpController.go

@@ -49,7 +49,7 @@ func securityCheckServer(adminonly bool, next http.Handler) http.HandlerFunc {
 		if !adminonly && (err != nil || user == "") {
 			returnErrorResponse(w, r, errorResponse)
 			return
-		} 
+		}
 		if adminonly && !isadmin && !authenticateMasterServer(authToken) {
 			returnErrorResponse(w, r, errorResponse)
 			return

+ 39 - 29
controllers/userHttpController.go

@@ -28,11 +28,11 @@ func userHandlers(r *mux.Router) {
 	r.HandleFunc("/api/users", authorizeUserAdm(http.HandlerFunc(getUsers))).Methods("GET")
 }
 
-//Node authenticates using its password and retrieves a JWT for authorization.
+// Node authenticates using its password and retrieves a JWT for authorization.
 func authenticateUser(response http.ResponseWriter, request *http.Request) {
 
-	//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"
+	// 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.UserAuthParams
 	var errorResponse = models.ErrorResponse{
 		Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
@@ -53,7 +53,7 @@ func authenticateUser(response http.ResponseWriter, request *http.Request) {
 	}
 
 	if jwt == "" {
-		//very unlikely that err is !nil and no jwt returned, but handle it anyways.
+		// very unlikely that err is !nil and no jwt returned, but handle it anyways.
 		returnErrorResponse(response, request, formatError(errors.New("No token returned"), "internal"))
 		return
 	}
@@ -67,7 +67,7 @@ func authenticateUser(response http.ResponseWriter, request *http.Request) {
 			UserName:  username,
 		},
 	}
-	//Send back the JWT
+	// Send back the JWT
 	successJSONResponse, jsonError := json.Marshal(successResponse)
 
 	if jsonError != nil {
@@ -79,6 +79,7 @@ func authenticateUser(response http.ResponseWriter, request *http.Request) {
 	response.Write(successJSONResponse)
 }
 
+// VerifyAuthRequest - verifies an auth request
 func VerifyAuthRequest(authRequest models.UserAuthParams) (string, error) {
 	var result models.User
 	if authRequest.UserName == "" {
@@ -86,7 +87,7 @@ func VerifyAuthRequest(authRequest models.UserAuthParams) (string, error) {
 	} else if authRequest.Password == "" {
 		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).
+	//Search DB for node with Mac Address. Ignore pending nodes (they should not be able to authenticate with API until approved).
 	record, err := database.FetchRecord(database.USERS_TABLE_NAME, authRequest.UserName)
 	if err != nil {
 		return "", errors.New("incorrect credentials")
@@ -95,9 +96,9 @@ func VerifyAuthRequest(authRequest models.UserAuthParams) (string, error) {
 		return "", errors.New("incorrect credentials")
 	}
 
-	//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
+	// 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
 	if err = bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(authRequest.Password)); err != nil {
 		return "", errors.New("incorrect credentials")
 	}
@@ -107,19 +108,19 @@ func VerifyAuthRequest(authRequest models.UserAuthParams) (string, error) {
 	return tokenString, nil
 }
 
-//The middleware for most requests to the API
-//They all pass  through here first
-//This will validate the JWT (or check for master token)
-//This will also check against the authNetwork and make sure the node should be accessing that endpoint,
-//even if it's technically ok
-//This is kind of a poor man's RBAC. There's probably a better/smarter way.
-//TODO: Consider better RBAC implementations
+// The middleware for most requests to the API
+// They all pass  through here first
+// This will validate the JWT (or check for master token)
+// This will also check against the authNetwork and make sure the node should be accessing that endpoint,
+// even if it's technically ok
+// This is kind of a poor man's RBAC. There's probably a better/smarter way.
+// TODO: Consider better RBAC implementations
 func authorizeUser(next http.Handler) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
 		w.Header().Set("Content-Type", "application/json")
 		var params = mux.Vars(r)
 
-		//get the auth token
+		// get the auth token
 		bearerToken := r.Header.Get("Authorization")
 		username := params["username"]
 		err := ValidateUserToken(bearerToken, username, false)
@@ -150,6 +151,7 @@ func authorizeUserAdm(next http.Handler) http.HandlerFunc {
 	}
 }
 
+// ValidateUserToken - self explained
 func ValidateUserToken(token string, user string, adminonly bool) error {
 	var tokenSplit = strings.Split(token, " ")
 	//I put this in in case the user doesn't put in a token at all (in which case it's empty)
@@ -179,6 +181,7 @@ func ValidateUserToken(token string, user string, adminonly bool) error {
 	return nil
 }
 
+// HasAdmin - checks if server has an admin
 func HasAdmin() (bool, error) {
 
 	collection, err := database.FetchRecords(database.USERS_TABLE_NAME)
@@ -218,6 +221,7 @@ func hasAdmin(w http.ResponseWriter, r *http.Request) {
 
 }
 
+// GetUser - gets a user
 func GetUser(username string) (models.ReturnUser, error) {
 
 	var user models.ReturnUser
@@ -231,6 +235,7 @@ func GetUser(username string) (models.ReturnUser, error) {
 	return user, err
 }
 
+// GetUserInternal - gets an internal user
 func GetUserInternal(username string) (models.User, error) {
 
 	var user models.User
@@ -244,6 +249,7 @@ func GetUserInternal(username string) (models.User, error) {
 	return user, err
 }
 
+// GetUsers - gets users
 func GetUsers() ([]models.ReturnUser, error) {
 
 	var users []models.ReturnUser
@@ -267,7 +273,7 @@ func GetUsers() ([]models.ReturnUser, error) {
 	return users, err
 }
 
-//Get an individual node. Nothin fancy here folks.
+// Get an individual node. Nothin fancy here folks.
 func getUser(w http.ResponseWriter, r *http.Request) {
 	// set header.
 	w.Header().Set("Content-Type", "application/json")
@@ -284,7 +290,7 @@ func getUser(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(user)
 }
 
-//Get an individual node. Nothin fancy here folks.
+// Get an individual node. Nothin fancy here folks.
 func getUsers(w http.ResponseWriter, r *http.Request) {
 	// set header.
 	w.Header().Set("Content-Type", "application/json")
@@ -300,8 +306,9 @@ func getUsers(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(users)
 }
 
+// CreateUser - creates a user
 func CreateUser(user models.User) (models.User, error) {
-	//check if user exists
+	// check if user exists
 	if _, err := GetUser(user.UserName); err == nil {
 		return models.User{}, errors.New("user exists")
 	}
@@ -310,18 +317,18 @@ func CreateUser(user models.User) (models.User, error) {
 		return models.User{}, err
 	}
 
-	//encrypt that password so we never see it again
+	// encrypt that password so we never see it again
 	hash, err := bcrypt.GenerateFromPassword([]byte(user.Password), 5)
 	if err != nil {
 		return user, err
 	}
-	//set password to encrypted password
+	// set password to encrypted password
 	user.Password = string(hash)
 
 	tokenString, _ := functions.CreateUserJWT(user.UserName, user.Networks, user.IsAdmin)
 
 	if tokenString == "" {
-		//returnErrorResponse(w, r, errorResponse)
+		// returnErrorResponse(w, r, errorResponse)
 		return user, err
 	}
 
@@ -339,7 +346,7 @@ func createAdmin(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "application/json")
 
 	var admin models.User
-	//get node from body of request
+	// get node from body of request
 	_ = json.NewDecoder(r.Body).Decode(&admin)
 	admin.IsAdmin = true
 	admin, err := CreateUser(admin)
@@ -356,7 +363,7 @@ func createUser(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "application/json")
 
 	var user models.User
-	//get node from body of request
+	// get node from body of request
 	_ = json.NewDecoder(r.Body).Decode(&user)
 
 	user, err := CreateUser(user)
@@ -369,6 +376,7 @@ func createUser(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(user)
 }
 
+// UpdateUser - updates a given user
 func UpdateUser(userchange models.User, user models.User) (models.User, error) {
 	//check if user exists
 	if _, err := GetUser(user.UserName); err != nil {
@@ -389,13 +397,13 @@ func UpdateUser(userchange models.User, user models.User) (models.User, error) {
 		user.Networks = userchange.Networks
 	}
 	if userchange.Password != "" {
-		//encrypt that password so we never see it again
+		// encrypt that password so we never see it again
 		hash, err := bcrypt.GenerateFromPassword([]byte(userchange.Password), 5)
 
 		if err != nil {
 			return userchange, err
 		}
-		//set password to encrypted password
+		// set password to encrypted password
 		userchange.Password = string(hash)
 
 		user.Password = userchange.Password
@@ -418,7 +426,7 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "application/json")
 	var params = mux.Vars(r)
 	var user models.User
-	//start here
+	// start here
 	username := params["username"]
 	user, err := GetUserInternal(username)
 	if err != nil {
@@ -446,7 +454,7 @@ func updateUserAdm(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "application/json")
 	var params = mux.Vars(r)
 	var user models.User
-	//start here
+	// start here
 	username := params["username"]
 	user, err := GetUserInternal(username)
 	if err != nil {
@@ -469,6 +477,7 @@ func updateUserAdm(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(user)
 }
 
+// DeleteUser - deletes a given user
 func DeleteUser(user string) (bool, error) {
 
 	if userRecord, err := database.FetchRecord(database.USERS_TABLE_NAME, user); err != nil || len(userRecord) == 0 {
@@ -504,6 +513,7 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(params["username"] + " deleted.")
 }
 
+// ValidateUser - validates a user model
 func ValidateUser(operation string, user models.User) error {
 
 	v := validator.New()

+ 5 - 3
database/database.go

@@ -2,10 +2,10 @@ package database
 
 import (
 	"encoding/json"
-	"time"
 	"errors"
-	"log"
 	"github.com/gravitl/netmaker/servercfg"
+	"log"
+	"time"
 )
 
 const NETWORKS_TABLE_NAME = "networks"
@@ -38,13 +38,15 @@ func getCurrentDB() map[string]interface{} {
 		return RQLITE_FUNCTIONS
 	case "sqlite":
 		return SQLITE_FUNCTIONS
+	case "postgres":
+		return PG_FUNCTIONS
 	default:
 		return SQLITE_FUNCTIONS
 	}
 }
 
 func InitializeDatabase() error {
-	log.Println("connecting to",servercfg.GetDB())
+	log.Println("connecting to", servercfg.GetDB())
 	tperiod := time.Now().Add(10 * time.Second)
 	for {
 		if err := getCurrentDB()[INIT_DB].(func() error)(); err != nil {

+ 131 - 0
database/postgres.go

@@ -0,0 +1,131 @@
+package database
+
+import (
+	"github.com/gravitl/netmaker/servercfg"
+	"database/sql"
+	"errors"
+	_ "github.com/lib/pq"
+	"fmt"
+)
+
+var PGDB *sql.DB
+
+var PG_FUNCTIONS = map[string]interface{}{
+	INIT_DB:      initPGDB,
+	CREATE_TABLE: pgCreateTable,
+	INSERT:       pgInsert,
+	INSERT_PEER:  pgInsertPeer,
+	DELETE:       pgDeleteRecord,
+	DELETE_ALL:   pgDeleteAllRecords,
+	FETCH_ALL:    pgFetchRecords,
+	CLOSE_DB:     pgCloseDB,
+}
+
+func getPGConnString() string{
+	pgconf := servercfg.GetSQLConf()
+	pgConn := fmt.Sprintf("host=%s port=%d user=%s "+
+	  "password=%s dbname=%s sslmode=%s",
+	  pgconf.Host, pgconf.Port, pgconf.Username, pgconf.Password, pgconf.DB, pgconf.SSLMode)
+	return pgConn
+}
+  
+
+func initPGDB() error {
+	connString := getPGConnString()
+	var dbOpenErr error
+	PGDB, dbOpenErr = sql.Open("postgres", connString)
+	if dbOpenErr != nil {
+		return dbOpenErr
+	}
+	dbOpenErr = PGDB.Ping()
+
+	return dbOpenErr
+}
+
+func pgCreateTable(tableName string) error {
+	statement, err := PGDB.Prepare("CREATE TABLE IF NOT EXISTS " + tableName + " (key TEXT NOT NULL UNIQUE PRIMARY KEY, value TEXT)")
+	if err != nil {
+		return err
+	}
+	_, err = statement.Exec()
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func pgInsert(key string, value string, tableName string) error {
+	if key != "" && value != "" && IsJSONString(value) {
+		insertSQL := "INSERT INTO " + tableName + " (key, value) VALUES ($1, $2) ON CONFLICT (key) DO UPDATE SET value = $3;"
+		statement, err := PGDB.Prepare(insertSQL)
+		if err != nil {
+			return err
+		}
+		_, err = statement.Exec(key, value, value)
+		if err != nil {
+			return err
+		}
+		return nil
+	} else {
+		return errors.New("invalid insert " + key + " : " + value)
+	}
+}
+
+func pgInsertPeer(key string, value string) error {
+	if key != "" && value != "" && IsJSONString(value) {
+		err := pgInsert(key, value, PEERS_TABLE_NAME)
+		if err != nil {
+			return err
+		}
+		return nil
+	} else {
+		return errors.New("invalid peer insert " + key + " : " + value)
+	}
+}
+
+func pgDeleteRecord(tableName string, key string) error {
+	deleteSQL := "DELETE FROM " + tableName + " WHERE key = $1;"
+	statement, err := PGDB.Prepare(deleteSQL)
+	if err != nil {
+		return err
+	}
+	if _, err = statement.Exec(key); err != nil {
+		return err
+	}
+	return nil
+}
+
+func pgDeleteAllRecords(tableName string) error {
+	deleteSQL := "DELETE FROM " + tableName
+	statement, err := PGDB.Prepare(deleteSQL)
+	if err != nil {
+		return err
+	}
+	if _, err = statement.Exec(); err != nil {
+		return err
+	}
+	return nil
+}
+
+func pgFetchRecords(tableName string) (map[string]string, error) {
+	row, err := PGDB.Query("SELECT * FROM " + tableName + " ORDER BY key")
+	if err != nil {
+		return nil, err
+	}
+	records := make(map[string]string)
+	defer row.Close()
+	for row.Next() { // Iterate and fetch the records from result cursor
+		var key string
+		var value string
+		row.Scan(&key, &value)
+		records[key] = value
+	}
+	if len(records) == 0 {
+		return nil, errors.New(NO_RECORDS)
+	}
+	return records, nil
+}
+
+func pgCloseDB() {
+	PGDB.Close()
+}

+ 4 - 4
database/rqlite.go

@@ -7,8 +7,10 @@ import (
 	"github.com/rqlite/gorqlite"
 )
 
+// RQliteDatabase - the rqlite db connection
 var RQliteDatabase gorqlite.Connection
 
+// RQLITE_FUNCTIONS - all the functions to run with rqlite
 var RQLITE_FUNCTIONS = map[string]interface{}{
 	INIT_DB:      initRqliteDatabase,
 	CREATE_TABLE: rqliteCreateTable,
@@ -46,9 +48,8 @@ func rqliteInsert(key string, value string, tableName string) error {
 			return err
 		}
 		return nil
-	} else {
-		return errors.New("invalid insert " + key + " : " + value)
 	}
+	return errors.New("invalid insert " + key + " : " + value)
 }
 
 func rqliteInsertPeer(key string, value string) error {
@@ -58,9 +59,8 @@ func rqliteInsertPeer(key string, value string) error {
 			return err
 		}
 		return nil
-	} else {
-		return errors.New("invalid peer insert " + key + " : " + value)
 	}
+	return errors.New("invalid peer insert " + key + " : " + value)
 }
 
 func rqliteDeleteRecord(tableName string, key string) error {

+ 5 - 5
database/sqlite.go

@@ -6,14 +6,16 @@ import (
 	"os"
 	"path/filepath"
 
-	_ "github.com/mattn/go-sqlite3"
+	_ "github.com/mattn/go-sqlite3" // need to blank import this package
 )
 
 // == sqlite ==
 const dbFilename = "netmaker.db"
 
+// SqliteDB is the db object fro sqlite database connections
 var SqliteDB *sql.DB
 
+// SQLITE_FUNCTIONS - contains a map of the functions for sqlite
 var SQLITE_FUNCTIONS = map[string]interface{}{
 	INIT_DB:      initSqliteDB,
 	CREATE_TABLE: sqliteCreateTable,
@@ -67,9 +69,8 @@ func sqliteInsert(key string, value string, tableName string) error {
 			return err
 		}
 		return nil
-	} else {
-		return errors.New("invalid insert " + key + " : " + value)
 	}
+	return errors.New("invalid insert " + key + " : " + value)
 }
 
 func sqliteInsertPeer(key string, value string) error {
@@ -79,9 +80,8 @@ func sqliteInsertPeer(key string, value string) error {
 			return err
 		}
 		return nil
-	} else {
-		return errors.New("invalid peer insert " + key + " : " + value)
 	}
+	return errors.New("invalid peer insert " + key + " : " + value)
 }
 
 func sqliteDeleteRecord(tableName string, key string) error {

+ 5 - 0
database/statics.go

@@ -5,6 +5,7 @@ import (
 	"strings"
 )
 
+// SetPeers - sets peers for a network
 func SetPeers(newPeers map[string]string, networkName string) bool {
 	areEqual := PeersAreEqual(newPeers, networkName)
 	if !areEqual {
@@ -17,6 +18,8 @@ func SetPeers(newPeers map[string]string, networkName string) bool {
 	}
 	return !areEqual
 }
+
+// GetPeers - gets peers for a given network
 func GetPeers(networkName string) (map[string]string, error) {
 	record, err := FetchRecord(PEERS_TABLE_NAME, networkName)
 	if err != nil && !IsEmptyRecord(err) {
@@ -30,6 +33,7 @@ func GetPeers(networkName string) (map[string]string, error) {
 	return currentDataMap, err
 }
 
+// PeersAreEqual - checks if peers are the same
 func PeersAreEqual(toCompare map[string]string, networkName string) bool {
 	currentDataMap, err := GetPeers(networkName)
 	if err != nil {
@@ -46,6 +50,7 @@ func PeersAreEqual(toCompare map[string]string, networkName string) bool {
 	return true
 }
 
+// IsEmptyRecord - checks for if it's an empty record error or not
 func IsEmptyRecord(err error) bool {
 	if err == nil {
 		return false

+ 4 - 0
dnslogic/dns.go

@@ -10,6 +10,7 @@ import (
 	"github.com/txn2/txeh"
 )
 
+// SetDNS - sets the dns on file
 func SetDNS() error {
 	hostfile := txeh.Hosts{}
 	var corefilestring string
@@ -42,6 +43,7 @@ func SetDNS() error {
 	return err
 }
 
+// GetDNS - gets the DNS of a current network
 func GetDNS(network string) ([]models.DNSEntry, error) {
 
 	var dns []models.DNSEntry
@@ -58,6 +60,7 @@ func GetDNS(network string) ([]models.DNSEntry, error) {
 	return dns, nil
 }
 
+// GetNodeDNS - gets the DNS of a network node
 func GetNodeDNS(network string) ([]models.DNSEntry, error) {
 
 	var dns []models.DNSEntry
@@ -81,6 +84,7 @@ func GetNodeDNS(network string) ([]models.DNSEntry, error) {
 	return dns, nil
 }
 
+// GetCustomDNS - gets the custom DNS of a network
 func GetCustomDNS(network string) ([]models.DNSEntry, error) {
 
 	var dns []models.DNSEntry

+ 16 - 0
docker/Dockerfile-userspace

@@ -0,0 +1,16 @@
+ARG NM_VERSION=
+
+FROM gravitl/builder as builder
+
+RUN apk add --update git build-base libmnl-dev iptables
+
+WORKDIR /root/
+RUN git clone https://git.zx2c4.com/wireguard-go && \
+    cd wireguard-go && \
+    make && \
+    make install
+
+FROM gravitl/netmaker:${NM_VERSION}
+
+RUN apk add --no-cache --update libmnl iptables openresolv iproute2
+COPY --from=builder /usr/bin/wireguard-go /usr/bin/wg* /usr/bin/

+ 23 - 0
docker/Dockerfile-wg-quick

@@ -0,0 +1,23 @@
+ARG NM_VERSION=
+
+FROM gravitl/builder as builder
+
+RUN apk add --update git build-base libmnl-dev iptables
+
+WORKDIR /root/
+RUN git clone https://git.zx2c4.com/wireguard-go && \
+    cd wireguard-go && \
+    make && \
+    make install
+
+ENV WITH_WGQUICK=yes
+RUN git clone https://git.zx2c4.com/wireguard-tools && \
+    cd wireguard-tools && \
+    cd src && \
+    make && \
+    make install
+
+FROM gravitl/netmaker:${NM_VERSION}
+
+RUN apk add --no-cache --update bash libmnl iptables openresolv iproute2
+COPY --from=builder /usr/bin/wireguard-go /usr/bin/wg* /usr/bin/

+ 50 - 3
functions/helpers.go

@@ -20,6 +20,7 @@ import (
 	"github.com/gravitl/netmaker/servercfg"
 )
 
+// PrintUserLog - prints a log with a given username
 func PrintUserLog(username string, message string, loglevel int) {
 	log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
 	if int32(loglevel) <= servercfg.GetVerbose() && servercfg.GetVerbose() != 0 {
@@ -27,24 +28,28 @@ func PrintUserLog(username string, message string, loglevel int) {
 	}
 }
 
+// ParseNetwork - parses a network into a model
 func ParseNetwork(value string) (models.Network, error) {
 	var network models.Network
 	err := json.Unmarshal([]byte(value), &network)
 	return network, err
 }
 
+// ParseNode - parses a node into a model
 func ParseNode(value string) (models.Node, error) {
 	var node models.Node
 	err := json.Unmarshal([]byte(value), &node)
 	return node, err
 }
 
+// ParseExtClient - parses an extclient into a model
 func ParseExtClient(value string) (models.ExtClient, error) {
 	var extClient models.ExtClient
 	err := json.Unmarshal([]byte(value), &extClient)
 	return extClient, err
 }
 
+// ParseIntClient - parses int client
 func ParseIntClient(value string) (models.IntClient, error) {
 	var intClient models.IntClient
 	err := json.Unmarshal([]byte(value), &intClient)
@@ -54,6 +59,7 @@ func ParseIntClient(value string) (models.IntClient, error) {
 //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
 
+// GetUser - gets a user
 func GetUser(username string) (models.User, error) {
 
 	var user models.User
@@ -67,6 +73,7 @@ func GetUser(username string) (models.User, error) {
 	return user, err
 }
 
+// SliceContains - sees if a slice contains something
 func SliceContains(slice []string, item string) bool {
 	set := make(map[string]struct{}, len(slice))
 	for _, s := range slice {
@@ -77,6 +84,7 @@ func SliceContains(slice []string, item string) bool {
 	return ok
 }
 
+// CreateServerToken - creates a server token
 func CreateServerToken(netID string) (string, error) {
 	var network models.Network
 	var accesskey models.AccessKey
@@ -130,6 +138,7 @@ func CreateServerToken(netID string) (string, error) {
 	return accesskey.AccessString, nil
 }
 
+// GetPeersList - gets peers for given network
 func GetPeersList(networkName string) ([]models.PeersResponse, error) {
 
 	var peers []models.PeersResponse
@@ -151,6 +160,7 @@ func GetPeersList(networkName string) ([]models.PeersResponse, error) {
 	return peers, err
 }
 
+// GetIntPeersList - get int peers list
 func GetIntPeersList() ([]models.PeersResponse, error) {
 
 	var peers []models.PeersResponse
@@ -176,6 +186,7 @@ func GetIntPeersList() ([]models.PeersResponse, error) {
 	return peers, err
 }
 
+// GetServerIntClient - get server int client
 func GetServerIntClient() (*models.IntClient, error) {
 
 	intClients, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
@@ -192,6 +203,7 @@ func GetServerIntClient() (*models.IntClient, error) {
 	return nil, err
 }
 
+// NetworkExists - check if network exists
 func NetworkExists(name string) (bool, error) {
 
 	var network string
@@ -201,6 +213,8 @@ func NetworkExists(name string) (bool, error) {
 	}
 	return len(network) > 0, nil
 }
+
+// GetRecordKey - get record key
 func GetRecordKey(id string, network string) (string, error) {
 	if id == "" || network == "" {
 		return "", errors.New("unable to get record key")
@@ -208,6 +222,7 @@ func GetRecordKey(id string, network string) (string, error) {
 	return id + "###" + network, nil
 }
 
+// UpdateNetworkNodeAddresses - updates network node addresses
 func UpdateNetworkNodeAddresses(networkName string) error {
 
 	collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
@@ -244,6 +259,7 @@ func UpdateNetworkNodeAddresses(networkName string) error {
 	return nil
 }
 
+// NetworkNodesUpdateAction - updates action of network nodes
 func NetworkNodesUpdateAction(networkName string, action string) error {
 
 	collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
@@ -277,6 +293,7 @@ func NetworkNodesUpdateAction(networkName string, action string) error {
 	return nil
 }
 
+// NetworkNodesUpdatePullChanges - tells nodes on network to pull
 func NetworkNodesUpdatePullChanges(networkName string) error {
 
 	collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
@@ -308,6 +325,7 @@ func NetworkNodesUpdatePullChanges(networkName string) error {
 	return nil
 }
 
+// UpdateNetworkLocalAddresses - updates network localaddresses
 func UpdateNetworkLocalAddresses(networkName string) error {
 
 	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
@@ -346,6 +364,7 @@ func UpdateNetworkLocalAddresses(networkName string) error {
 	return nil
 }
 
+// IsNetworkDisplayNameUnique - checks if network display name unique
 func IsNetworkDisplayNameUnique(name string) (bool, error) {
 
 	isunique := true
@@ -365,6 +384,7 @@ func IsNetworkDisplayNameUnique(name string) (bool, error) {
 	return isunique, nil
 }
 
+// IsMacAddressUnique - checks if mac is unique
 func IsMacAddressUnique(macaddress string, networkName string) (bool, error) {
 
 	_, err := database.FetchRecord(database.NODES_TABLE_NAME, macaddress+"###"+networkName)
@@ -375,6 +395,7 @@ func IsMacAddressUnique(macaddress string, networkName string) (bool, error) {
 	return true, nil
 }
 
+// GetNetworkNonServerNodeCount - get number of network non server nodes
 func GetNetworkNonServerNodeCount(networkName string) (int, error) {
 
 	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
@@ -400,6 +421,8 @@ func GetNetworkNonServerNodeCount(networkName string) (int, error) {
 //Does so by checking against all keys and seeing if any have the same value
 //may want to hash values before comparing...consider this
 //TODO: No error handling!!!!
+
+// IsKeyValid - check if key is valid
 func IsKeyValid(networkname string, keyvalue string) bool {
 
 	network, _ := GetParentNetwork(networkname)
@@ -422,6 +445,7 @@ func IsKeyValid(networkname string, keyvalue string) bool {
 	return isvalid
 }
 
+// IsKeyValidGlobal - checks if a key is valid globally
 func IsKeyValidGlobal(keyvalue string) bool {
 
 	networks, _ := models.GetNetworks()
@@ -453,6 +477,8 @@ func IsKeyValidGlobal(keyvalue string) bool {
 //This just gets a network object from a network name
 //Should probably just be GetNetwork. kind of a dumb name.
 //Used in contexts where it's not the Parent network.
+
+// GetParentNetwork - get parent network
 func GetParentNetwork(networkname string) (models.Network, error) {
 
 	var network models.Network
@@ -466,6 +492,7 @@ func GetParentNetwork(networkname string) (models.Network, error) {
 	return network, nil
 }
 
+// IsIpNet - checks if valid ip
 func IsIpNet(host string) bool {
 	return net.ParseIP(host) != nil
 }
@@ -473,6 +500,8 @@ func IsIpNet(host string) bool {
 //Similar to above but checks if Cidr range is valid
 //At least this guy's got some print statements
 //still not good error handling
+
+// IsIpCIDR - IsIpCIDR
 func IsIpCIDR(host string) bool {
 
 	ip, ipnet, err := net.ParseCIDR(host)
@@ -488,6 +517,8 @@ func IsIpCIDR(host string) bool {
 
 //This  checks to  make sure a network name is valid.
 //Switch to REGEX?
+
+// NameInNetworkCharSet - see if name is in charset for networks
 func NameInNetworkCharSet(name string) bool {
 
 	charset := "abcdefghijklmnopqrstuvwxyz1234567890-_."
@@ -500,6 +531,7 @@ func NameInNetworkCharSet(name string) bool {
 	return true
 }
 
+// NameInDNSCharSet - name in dns char set
 func NameInDNSCharSet(name string) bool {
 
 	charset := "abcdefghijklmnopqrstuvwxyz1234567890-."
@@ -512,6 +544,7 @@ func NameInDNSCharSet(name string) bool {
 	return true
 }
 
+// NameInNodeCharSet - name in node char set
 func NameInNodeCharSet(name string) bool {
 
 	charset := "abcdefghijklmnopqrstuvwxyz1234567890-"
@@ -528,6 +561,8 @@ func NameInNodeCharSet(name string) bool {
 //The mac address acts as the Unique ID for nodes.
 //Is this a dumb thing to do? I thought it was cool but maybe it's dumb.
 //It doesn't really provide a tangible benefit over a random ID
+
+// GetNodeByMacAddress - gets a node by mac address
 func GetNodeByMacAddress(network string, macaddress string) (models.Node, error) {
 
 	var node models.Node
@@ -551,6 +586,7 @@ func GetNodeByMacAddress(network string, macaddress string) (models.Node, error)
 	return node, nil
 }
 
+// GetDeletedNodeByMacAddress - get a deleted node
 func GetDeletedNodeByMacAddress(network string, macaddress string) (models.Node, error) {
 
 	var node models.Node
@@ -574,10 +610,12 @@ func GetDeletedNodeByMacAddress(network string, macaddress string) (models.Node,
 	return node, nil
 }
 
+// RemoveDeletedNode - remove deleted node
 func RemoveDeletedNode(nodeid string) bool {
 	return database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, nodeid) == nil
 }
 
+// DeleteAllIntClients - delete all int clients
 func DeleteAllIntClients() error {
 	err := database.DeleteAllRecords(database.INT_CLIENTS_TABLE_NAME)
 	if err != nil {
@@ -586,6 +624,7 @@ func DeleteAllIntClients() error {
 	return nil
 }
 
+// GetAllIntClients - get all int clients
 func GetAllIntClients() ([]models.IntClient, error) {
 	var clients []models.IntClient
 	collection, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
@@ -607,6 +646,7 @@ func GetAllIntClients() ([]models.IntClient, error) {
 	return clients, nil
 }
 
+// GetAllExtClients - get all ext clients
 func GetAllExtClients() ([]models.ExtClient, error) {
 	var extclients []models.ExtClient
 	collection, err := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME)
@@ -633,6 +673,8 @@ func GetAllExtClients() ([]models.ExtClient, error) {
 //and checks against all nodes to see if it's taken, until it finds one.
 //TODO: We do not handle a case where we run out of addresses.
 //We will need to handle that eventually
+
+// UniqueAddress - see if address is unique
 func UniqueAddress(networkName string) (string, error) {
 
 	var network models.Network
@@ -669,6 +711,7 @@ func UniqueAddress(networkName string) (string, error) {
 	return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
 }
 
+// UniqueAddress6 - see if ipv6 address is unique
 func UniqueAddress6(networkName string) (string, error) {
 
 	var network models.Network
@@ -701,7 +744,7 @@ func UniqueAddress6(networkName string) (string, error) {
 	return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
 }
 
-//generate an access key value
+// GenKey - generates access key
 func GenKey() string {
 
 	var seededRand *rand.Rand = rand.New(
@@ -721,6 +764,8 @@ func GenKey() string {
 //we should probably just have 1 random string generator
 //that  can be used across all functions
 //have a "base string" a "length" and a "charset"
+
+// GenKeyName - generates a key name
 func GenKeyName() string {
 
 	var seededRand *rand.Rand = rand.New(
@@ -736,6 +781,7 @@ func GenKeyName() string {
 	return "key" + string(b)
 }
 
+// IsIPUnique - checks if an IP is unique
 func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
 
 	isunique := true
@@ -766,6 +812,7 @@ func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
 
 //called once key has been used by createNode
 //reduces value by one and deletes if necessary
+// DecrimentKey - decriments key uses
 func DecrimentKey(networkName string, keyvalue string) {
 
 	var network models.Network
@@ -796,7 +843,7 @@ func DecrimentKey(networkName string, keyvalue string) {
 	}
 }
 
-//takes the logic from controllers.deleteKey
+// DeleteKey - deletes a key
 func DeleteKey(network models.Network, i int) {
 
 	network.AccessKeys = append(network.AccessKeys[:i],
@@ -809,7 +856,7 @@ func DeleteKey(network models.Network, i int) {
 	}
 }
 
-//increments an IP over the previous
+// Inc - increments an IP
 func Inc(ip net.IP) {
 	for j := len(ip) - 1; j >= 0; j-- {
 		ip[j]++

+ 3 - 1
functions/jwt.go

@@ -3,6 +3,7 @@ package functions
 import (
 	"errors"
 	"time"
+
 	"github.com/golang-jwt/jwt/v4"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/servercfg"
@@ -29,6 +30,7 @@ func CreateJWT(macaddress string, network string) (response string, err error) {
 	return "", err
 }
 
+// CreateUserJWT - creates a user jwt token
 func CreateUserJWT(username string, networks []string, isadmin bool) (response string, err error) {
 	expirationTime := time.Now().Add(60 * 12 * time.Minute)
 	claims := &models.UserClaims{
@@ -70,7 +72,7 @@ func VerifyUserToken(tokenString string) (username string, networks []string, is
 	return "", nil, false, err
 }
 
-// GRPC [nodes] Only
+// VerifyToken - gRPC [nodes] Only
 func VerifyToken(tokenString string) (macaddress string, network string, err error) {
 	claims := &models.Claims{}
 

+ 25 - 25
functions/local.go

@@ -14,31 +14,31 @@ func FileExists(f string) bool {
 }
 
 func SetDNSDir() error {
-        dir, err := os.Getwd()
-        if err != nil {
-                return err
-        }
-        _, err = os.Stat(dir + "/config/dnsconfig")
-        if os.IsNotExist(err) {
-                os.Mkdir(dir+"/config/dnsconfig", 0744)
-        } else if err != nil {
-                PrintUserLog("","couldnt find or create /config/dnsconfig",0)
-                return err
-        }
-		_, err = os.Stat(dir + "/config/dnsconfig/Corefile")
-        if os.IsNotExist(err) {
-			err = SetCorefile(".")
-			if err != nil {
-				PrintUserLog("",err.Error(),0)
-			}
+	dir, err := os.Getwd()
+	if err != nil {
+		return err
+	}
+	_, err = os.Stat(dir + "/config/dnsconfig")
+	if os.IsNotExist(err) {
+		os.Mkdir(dir+"/config/dnsconfig", 0744)
+	} else if err != nil {
+		PrintUserLog("", "couldnt find or create /config/dnsconfig", 0)
+		return err
+	}
+	_, err = os.Stat(dir + "/config/dnsconfig/Corefile")
+	if os.IsNotExist(err) {
+		err = SetCorefile(".")
+		if err != nil {
+			PrintUserLog("", err.Error(), 0)
 		}
-		_, err = os.Stat(dir + "/config/dnsconfig/netmaker.hosts")
-        if os.IsNotExist(err) {
-			_, err = os.Create(dir + "/config/dnsconfig/netmaker.hosts")
-			if err != nil {
-				PrintUserLog("",err.Error(),0)
-			}
-		}		
+	}
+	_, err = os.Stat(dir + "/config/dnsconfig/netmaker.hosts")
+	if os.IsNotExist(err) {
+		_, err = os.Create(dir + "/config/dnsconfig/netmaker.hosts")
+		if err != nil {
+			PrintUserLog("", err.Error(), 0)
+		}
+	}
 	return nil
 }
 
@@ -51,7 +51,7 @@ func SetCorefile(domains string) error {
 	if os.IsNotExist(err) {
 		os.Mkdir(dir+"/config/dnsconfig", 744)
 	} else if err != nil {
-		PrintUserLog("","couldnt find or create /config/dnsconfig",0)
+		PrintUserLog("", "couldnt find or create /config/dnsconfig", 0)
 		return err
 	}
 

+ 1 - 0
go.mod

@@ -8,6 +8,7 @@ require (
 	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/gorilla/handlers v1.5.1
 	github.com/gorilla/mux v1.8.0
+	github.com/lib/pq v1.10.3 // indirect
 	github.com/mattn/go-sqlite3 v1.14.8
 	github.com/rqlite/gorqlite v0.0.0-20210514125552-08ff1e76b22f
 	github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e

+ 2 - 0
go.sum

@@ -73,6 +73,8 @@ github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b h1:c3NTyLNozI
 github.com/jsimonetti/rtnetlink v0.0.0-20210212075122-66c871082f2b/go.mod h1:8w9Rh8m+aHZIG69YPGGem1i5VzoyRC8nw2kA8B+ik5U=
 github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
 github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
+github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg=
+github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU=
 github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=

+ 1 - 0
logic/extpeers.go

@@ -8,6 +8,7 @@ import (
 	"github.com/gravitl/netmaker/models"
 )
 
+// GetExtPeersList - gets the ext peers lists
 func GetExtPeersList(macaddress string, networkName string) ([]models.ExtPeersResponse, error) {
 
 	var peers []models.ExtPeersResponse

+ 4 - 0
logic/nodes.go

@@ -10,6 +10,7 @@ import (
 	"github.com/gravitl/netmaker/models"
 )
 
+// GetNetworkNodes - gets the nodes of a network
 func GetNetworkNodes(network string) ([]models.Node, error) {
 	var nodes []models.Node
 	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
@@ -33,6 +34,7 @@ func GetNetworkNodes(network string) ([]models.Node, error) {
 	return nodes, nil
 }
 
+// GetSortedNetworkServerNodes - gets nodes of a network, except sorted by update time
 func GetSortedNetworkServerNodes(network string) ([]models.Node, error) {
 	var nodes []models.Node
 	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
@@ -57,6 +59,7 @@ func GetSortedNetworkServerNodes(network string) ([]models.Node, error) {
 	return nodes, nil
 }
 
+// GetPeers - gets the peers of a given node
 func GetPeers(node models.Node) ([]models.Node, error) {
 	if node.IsServer == "yes" && IsLeader(&node) {
 		SetNetworkServerPeers(&node)
@@ -73,6 +76,7 @@ func GetPeers(node models.Node) ([]models.Node, error) {
 	return peers, nil
 }
 
+// IsLeader - determines if a given server node is a leader
 func IsLeader(node *models.Node) bool {
 	nodes, err := GetSortedNetworkServerNodes(node.Network)
 	if err != nil {

+ 11 - 4
logic/util.go

@@ -2,11 +2,11 @@
 package logic
 
 import (
+	"encoding/base64"
 	"encoding/json"
 	"strconv"
 	"strings"
 	"time"
-	"encoding/base64"
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/dnslogic"
 	"github.com/gravitl/netmaker/functions"
@@ -16,17 +16,20 @@ import (
 	"golang.org/x/crypto/bcrypt"
 )
 
-//This is used to validate public keys (make sure they're base64 encoded like all public keys should be).
+// IsBase64 - checks if a string is in base64 format
+// This is used to validate public keys (make sure they're base64 encoded like all public keys should be).
 func IsBase64(s string) bool {
 	_, err := base64.StdEncoding.DecodeString(s)
 	return err == nil
 }
 
+// CheckEndpoint - checks if an endpoint is valid
 func CheckEndpoint(endpoint string) bool {
 	endpointarr := strings.Split(endpoint, ":")
 	return len(endpointarr) == 2
 }
 
+// SetNetworkServerPeers - sets the network server peers of a given node
 func SetNetworkServerPeers(node *models.Node) {
 	if currentPeersList, err := GetSystemPeers(node); err == nil {
 		if database.SetPeers(currentPeersList, node.Network) {
@@ -38,7 +41,7 @@ func SetNetworkServerPeers(node *models.Node) {
 	}
 }
 
-
+// DeleteNode - deletes a node from database or moves into delete nodes table
 func DeleteNode(key string, exterminate bool) error {
 	var err error
 	if !exterminate {
@@ -70,7 +73,7 @@ func DeleteNode(key string, exterminate bool) error {
 	return err
 }
 
-
+// CreateNode - creates a node in database
 func CreateNode(node models.Node, networkName string) (models.Node, error) {
 
 	//encrypt that password so we never see it
@@ -130,6 +133,7 @@ func CreateNode(node models.Node, networkName string) (models.Node, error) {
 	return node, err
 }
 
+// SetNetworkNodesLastModified - sets the network nodes last modified
 func SetNetworkNodesLastModified(networkName string) error {
 
 	timestamp := time.Now().Unix()
@@ -150,6 +154,7 @@ func SetNetworkNodesLastModified(networkName string) error {
 	return nil
 }
 
+// GetNode - fetches a node from database
 func GetNode(macaddress string, network string) (models.Node, error) {
 	var node models.Node
 
@@ -173,6 +178,7 @@ func GetNode(macaddress string, network string) (models.Node, error) {
 	return node, err
 }
 
+// GetNodePeers - fetches peers for a given node
 func GetNodePeers(networkName string, excludeRelayed bool) ([]models.Node, error) {
 	var peers []models.Node
 	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
@@ -229,6 +235,7 @@ func GetNodePeers(networkName string, excludeRelayed bool) ([]models.Node, error
 	return peers, err
 }
 
+// GetPeersList - gets the peers of a given network
 func GetPeersList(networkName string, excludeRelayed bool, relayedNodeAddr string) ([]models.Node, error) {
 	var peers []models.Node
 	var relayNode models.Node

+ 1 - 0
logic/wireguard.go

@@ -5,6 +5,7 @@ import (
 	"golang.zx2c4.com/wireguard/wgctrl"
 )
 
+// GetSystemPeers - gets the server peers
 func GetSystemPeers(node *models.Node) (map[string]string, error) {
 	peers := make(map[string]string)
 

+ 1 - 1
main.go

@@ -156,7 +156,7 @@ func runGRPC(wg *sync.WaitGroup) {
 			log.Fatalf("Failed to serve: %v", err)
 		}
 	}()
-	log.Println("Agent Server succesfully started on port " + grpcport + " (gRPC)")
+	log.Println("Agent Server successfully started on port " + grpcport + " (gRPC)")
 
 	// Right way to stop the server using a SHUTDOWN HOOK
 	// Create a channel to receive OS signals

+ 17 - 17
models/accessToken.go

@@ -7,27 +7,27 @@ type AccessToken struct {
 }
 
 type ClientConfig struct {
-  Network string `json:"network"`
-  Key string `json:"key"`
-  LocalRange string `json:"localrange"`
+	Network    string `json:"network"`
+	Key        string `json:"key"`
+	LocalRange string `json:"localrange"`
 }
 
 type ServerConfig struct {
-  CoreDNSAddr string `json:"corednsaddr"`
-  APIConnString string `json:"apiconn"`
-  APIHost   string  `json:"apihost"`
-  APIPort   string `json:"apiport"`
-  GRPCConnString string `json:"grpcconn"`
-  GRPCHost   string `json:"grpchost"`
-  GRPCPort   string `json:"grpcport"`
-  GRPCSSL   string `json:"grpcssl"`
-  CheckinInterval   string `json:"checkininterval"`
+	CoreDNSAddr     string `json:"corednsaddr"`
+	APIConnString   string `json:"apiconn"`
+	APIHost         string `json:"apihost"`
+	APIPort         string `json:"apiport"`
+	GRPCConnString  string `json:"grpcconn"`
+	GRPCHost        string `json:"grpchost"`
+	GRPCPort        string `json:"grpcport"`
+	GRPCSSL         string `json:"grpcssl"`
+	CheckinInterval string `json:"checkininterval"`
 }
 
 type WG struct {
-  GRPCWireGuard  string  `json:"grpcwg"`
-  GRPCWGAddress  string `json:"grpcwgaddr"`
-  GRPCWGPort  string  `json:"grpcwgport"`
-  GRPCWGPubKey  string  `json:"grpcwgpubkey"`
-  GRPCWGEndpoint  string  `json:"grpcwgendpoint"`
+	GRPCWireGuard  string `json:"grpcwg"`
+	GRPCWGAddress  string `json:"grpcwgaddr"`
+	GRPCWGPort     string `json:"grpcwgport"`
+	GRPCWGPubKey   string `json:"grpcwgpubkey"`
+	GRPCWGEndpoint string `json:"grpcwgendpoint"`
 }

+ 2 - 4
models/extclient.go

@@ -6,6 +6,7 @@ import (
 	"github.com/gravitl/netmaker/database"
 )
 
+// ExtClient - struct for external clients
 type ExtClient struct {
 	ClientID               string `json:"clientid" bson:"clientid"`
 	Description            string `json:"description" bson:"description"`
@@ -18,10 +19,7 @@ type ExtClient struct {
 	LastModified           int64  `json:"lastmodified" bson:"lastmodified"`
 }
 
-/**
- * Get the egress gateway ips of a given ExtClient struct
- * returns as []string
- */
+// ExtClient.GetEgressRangesOnNetwork - returns the egress ranges on network of ext client
 func (client *ExtClient) GetEgressRangesOnNetwork() ([]string, error) {
 
 	var result []string

+ 14 - 14
models/intclient.go

@@ -1,18 +1,18 @@
 package models
 
 type IntClient struct {
-        ClientID       string             `json:"clientid" bson:"clientid"`
-        PrivateKey     string             `json:"privatekey" bson:"privatekey"`
-        PublicKey      string             `json:"publickey" bson:"publickey"`
-        AccessKey      string             `json:"accesskey" bson:"accesskey"`
-        Address        string             `json:"address" bson:"address"`
-        Address6       string             `json:"address6" bson:"address6"`
-        Network        string             `json:"network" bson:"network"`
-        ServerPublicEndpoint  string `json:"serverpublicendpoint" bson:"serverpublicendpoint"`
-        ServerAPIPort  string      `json:"serverapiport" bson:"serverapiport"`
-        ServerPrivateAddress  string       `json:"serverprivateaddress" bson:"serverprivateaddress"`
-        ServerWGPort     string             `json:"serverwgport" bson:"serverwgport"`
-        ServerGRPCPort     string             `json:"servergrpcport" bson:"servergrpcport"`
-        ServerKey      string             `json:"serverkey" bson:"serverkey"`
-        IsServer       string             `json:"isserver" bson:"isserver"`
+	ClientID             string `json:"clientid" bson:"clientid"`
+	PrivateKey           string `json:"privatekey" bson:"privatekey"`
+	PublicKey            string `json:"publickey" bson:"publickey"`
+	AccessKey            string `json:"accesskey" bson:"accesskey"`
+	Address              string `json:"address" bson:"address"`
+	Address6             string `json:"address6" bson:"address6"`
+	Network              string `json:"network" bson:"network"`
+	ServerPublicEndpoint string `json:"serverpublicendpoint" bson:"serverpublicendpoint"`
+	ServerAPIPort        string `json:"serverapiport" bson:"serverapiport"`
+	ServerPrivateAddress string `json:"serverprivateaddress" bson:"serverprivateaddress"`
+	ServerWGPort         string `json:"serverwgport" bson:"serverwgport"`
+	ServerGRPCPort       string `json:"servergrpcport" bson:"servergrpcport"`
+	ServerKey            string `json:"serverkey" bson:"serverkey"`
+	IsServer             string `json:"isserver" bson:"isserver"`
 }

+ 46 - 37
models/network.go

@@ -12,43 +12,45 @@ import (
 	"github.com/gravitl/netmaker/servercfg"
 )
 
-//Network Struct
+// Network Struct - contains info for a given unique network
 //At  some point, need to replace all instances of Name with something else like  Identifier
 type Network struct {
-	AddressRange           string      `json:"addressrange" bson:"addressrange" validate:"required,cidr"`
-	AddressRange6          string      `json:"addressrange6" bson:"addressrange6" validate:"regexp=^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$"`
-	DisplayName            string      `json:"displayname,omitempty" bson:"displayname,omitempty" validate:"omitempty,min=1,max=20,displayname_valid"`
-	NetID                  string      `json:"netid" bson:"netid" validate:"required,min=1,max=12,netid_valid"`
-	NodesLastModified      int64       `json:"nodeslastmodified" bson:"nodeslastmodified"`
-	NetworkLastModified    int64       `json:"networklastmodified" bson:"networklastmodified"`
-	DefaultInterface       string      `json:"defaultinterface" bson:"defaultinterface" validate:"min=1,max=15"`
-	DefaultListenPort      int32       `json:"defaultlistenport,omitempty" bson:"defaultlistenport,omitempty" validate:"omitempty,min=1024,max=65535"`
-	NodeLimit              int32       `json:"nodelimit" bson:"nodelimit"`
-	DefaultPostUp          string      `json:"defaultpostup" bson:"defaultpostup"`
-	DefaultPostDown        string      `json:"defaultpostdown" bson:"defaultpostdown"`
-	KeyUpdateTimeStamp     int64       `json:"keyupdatetimestamp" bson:"keyupdatetimestamp"`
-	DefaultKeepalive       int32       `json:"defaultkeepalive" bson:"defaultkeepalive" validate:"omitempty,max=1000"`
-	DefaultSaveConfig      string      `json:"defaultsaveconfig" bson:"defaultsaveconfig" validate:"checkyesorno"`
-	AccessKeys             []AccessKey `json:"accesskeys" bson:"accesskeys"`
-	AllowManualSignUp      string      `json:"allowmanualsignup" bson:"allowmanualsignup" validate:"checkyesorno"`
-	IsLocal                string      `json:"islocal" bson:"islocal" validate:"checkyesorno"`
-	IsDualStack            string      `json:"isdualstack" bson:"isdualstack" validate:"checkyesorno"`
-	IsIPv4                 string      `json:"isipv4" bson:"isipv4" validate:"checkyesorno"`
-	IsIPv6                 string      `json:"isipv6" bson:"isipv6" validate:"checkyesorno"`
-	IsGRPCHub              string      `json:"isgrpchub" bson:"isgrpchub" validate:"checkyesorno"`
-	LocalRange             string      `json:"localrange" bson:"localrange" validate:"omitempty,cidr"`
-	
+	AddressRange        string      `json:"addressrange" bson:"addressrange" validate:"required,cidr"`
+	AddressRange6       string      `json:"addressrange6" bson:"addressrange6" validate:"regexp=^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))?$"`
+	DisplayName         string      `json:"displayname,omitempty" bson:"displayname,omitempty" validate:"omitempty,min=1,max=20,displayname_valid"`
+	NetID               string      `json:"netid" bson:"netid" validate:"required,min=1,max=12,netid_valid"`
+	NodesLastModified   int64       `json:"nodeslastmodified" bson:"nodeslastmodified"`
+	NetworkLastModified int64       `json:"networklastmodified" bson:"networklastmodified"`
+	DefaultInterface    string      `json:"defaultinterface" bson:"defaultinterface" validate:"min=1,max=15"`
+	DefaultListenPort   int32       `json:"defaultlistenport,omitempty" bson:"defaultlistenport,omitempty" validate:"omitempty,min=1024,max=65535"`
+	NodeLimit           int32       `json:"nodelimit" bson:"nodelimit"`
+	DefaultPostUp       string      `json:"defaultpostup" bson:"defaultpostup"`
+	DefaultPostDown     string      `json:"defaultpostdown" bson:"defaultpostdown"`
+	KeyUpdateTimeStamp  int64       `json:"keyupdatetimestamp" bson:"keyupdatetimestamp"`
+	DefaultKeepalive    int32       `json:"defaultkeepalive" bson:"defaultkeepalive" validate:"omitempty,max=1000"`
+	DefaultSaveConfig   string      `json:"defaultsaveconfig" bson:"defaultsaveconfig" validate:"checkyesorno"`
+	AccessKeys          []AccessKey `json:"accesskeys" bson:"accesskeys"`
+	AllowManualSignUp   string      `json:"allowmanualsignup" bson:"allowmanualsignup" validate:"checkyesorno"`
+	IsLocal             string      `json:"islocal" bson:"islocal" validate:"checkyesorno"`
+	IsDualStack         string      `json:"isdualstack" bson:"isdualstack" validate:"checkyesorno"`
+	IsIPv4              string      `json:"isipv4" bson:"isipv4" validate:"checkyesorno"`
+	IsIPv6              string      `json:"isipv6" bson:"isipv6" validate:"checkyesorno"`
+	IsGRPCHub           string      `json:"isgrpchub" bson:"isgrpchub" validate:"checkyesorno"`
+	LocalRange          string      `json:"localrange" bson:"localrange" validate:"omitempty,cidr"`
+
 	// checkin interval is depreciated at the network level. Set on server with CHECKIN_INTERVAL
-	DefaultCheckInInterval int32       `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"`
-	DefaultUDPHolePunch    string      `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
-	DefaultExtClientDNS    string      `json:"defaultextclientdns" bson:"defaultextclientdns"`
-	DefaultMTU             int32       `json:"defaultmtu" bson:"defaultmtu"`
+	DefaultCheckInInterval int32  `json:"checkininterval,omitempty" bson:"checkininterval,omitempty" validate:"omitempty,numeric,min=2,max=100000"`
+	DefaultUDPHolePunch    string `json:"defaultudpholepunch" bson:"defaultudpholepunch" validate:"checkyesorno"`
+	DefaultExtClientDNS    string `json:"defaultextclientdns" bson:"defaultextclientdns"`
+	DefaultMTU             int32  `json:"defaultmtu" bson:"defaultmtu"`
 }
 
+// SaveData - sensitive fields of a network that should be kept the same
 type SaveData struct { // put sensitive fields here
 	NetID string `json:"netid" bson:"netid" validate:"required,min=1,max=12,netid_valid"`
 }
 
+// Network.NetIDInNetworkCharSet - checks if a netid of a network uses valid characters
 func (network *Network) NetIDInNetworkCharSet() bool {
 
 	charset := "abcdefghijklmnopqrstuvwxyz1234567890-_."
@@ -61,6 +63,7 @@ func (network *Network) NetIDInNetworkCharSet() bool {
 	return true
 }
 
+// Network.DisplayNameInNetworkCharSet - checks if displayname uses valid characters
 func (network *Network) DisplayNameInNetworkCharSet() bool {
 
 	charset := "abcdefghijklmnopqrstuvwxyz1234567890-_./;% ^#()!@$*"
@@ -73,7 +76,7 @@ func (network *Network) DisplayNameInNetworkCharSet() bool {
 	return true
 }
 
-// Anyway, returns all the networks
+// GetNetworks - returns all networks from database
 func GetNetworks() ([]Network, error) {
 	var networks []Network
 
@@ -95,6 +98,7 @@ func GetNetworks() ([]Network, error) {
 	return networks, err
 }
 
+// Network.IsNetworkDisplayNameUnique - checks if displayname is unique from other networks
 func (network *Network) IsNetworkDisplayNameUnique() (bool, error) {
 
 	isunique := true
@@ -115,7 +119,7 @@ func (network *Network) IsNetworkDisplayNameUnique() (bool, error) {
 	return isunique, nil
 }
 
-//Checks to see if any other networks have the same name (id)
+// Network.IsNetworkNameUnique - checks to see if any other networks have the same name (id)
 func (network *Network) IsNetworkNameUnique() (bool, error) {
 
 	isunique := true
@@ -136,6 +140,7 @@ func (network *Network) IsNetworkNameUnique() (bool, error) {
 	return isunique, nil
 }
 
+// Network.Validate - validates fields of an network struct
 func (network *Network) Validate(isUpdate bool) error {
 	v := validator.New()
 	_ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool {
@@ -168,16 +173,17 @@ func (network *Network) Validate(isUpdate bool) error {
 	return err
 }
 
-//TODO:
-//Not  sure if we  need the below two functions. Got rid  of one of the calls. May want  to revisit
+// Network.SetNodesLastModified - sets nodes last modified on network, depricated
 func (network *Network) SetNodesLastModified() {
 	network.NodesLastModified = time.Now().Unix()
 }
 
+// Network.SetNetworkLastModified - sets network last modified time
 func (network *Network) SetNetworkLastModified() {
 	network.NetworkLastModified = time.Now().Unix()
 }
 
+// Network.SetDefaults - sets default values for a network struct
 func (network *Network) SetDefaults() {
 	if network.DefaultUDPHolePunch == "" {
 		if servercfg.IsClientMode() != "off" {
@@ -237,6 +243,7 @@ func (network *Network) SetDefaults() {
 	}
 }
 
+// Network.Update - updates a network with another network's fields
 func (currentNetwork *Network) Update(newNetwork *Network) (bool, bool, error) {
 	if err := newNetwork.Validate(true); err != nil {
 		return false, false, err
@@ -244,18 +251,19 @@ func (currentNetwork *Network) Update(newNetwork *Network) (bool, bool, error) {
 	if newNetwork.NetID == currentNetwork.NetID {
 		hasrangeupdate := newNetwork.AddressRange != currentNetwork.AddressRange
 		localrangeupdate := newNetwork.LocalRange != currentNetwork.LocalRange
-		if data, err := json.Marshal(newNetwork); err != nil {
+		data, err := json.Marshal(newNetwork)
+		if err != nil {
 			return false, false, err
-		} else {
-			newNetwork.SetNetworkLastModified()
-			err = database.Insert(newNetwork.NetID, string(data), database.NETWORKS_TABLE_NAME)
-			return hasrangeupdate, localrangeupdate, err
 		}
+		newNetwork.SetNetworkLastModified()
+		err = database.Insert(newNetwork.NetID, string(data), database.NETWORKS_TABLE_NAME)
+		return hasrangeupdate, localrangeupdate, err
 	}
 	// copy values
 	return false, false, errors.New("failed to update network " + newNetwork.NetID + ", cannot change netid.")
 }
 
+// Network.SetNetworkNodesLastModified - sets network nodes last modified time
 func (network *Network) SetNetworkNodesLastModified() error {
 
 	timestamp := time.Now().Unix()
@@ -272,6 +280,7 @@ func (network *Network) SetNetworkNodesLastModified() error {
 	return nil
 }
 
+// GetNetwork - gets a network from database
 func GetNetwork(networkname string) (Network, error) {
 
 	var network Network

+ 5 - 5
models/node.go

@@ -1,16 +1,16 @@
 package models
 
 import (
+	"bytes"
 	"encoding/json"
 	"errors"
+	"github.com/go-playground/validator/v10"
+	"github.com/gravitl/netmaker/database"
+	"golang.org/x/crypto/bcrypt"
 	"math/rand"
 	"net"
 	"strings"
 	"time"
-	"bytes"
-	"github.com/go-playground/validator/v10"
-	"github.com/gravitl/netmaker/database"
-	"golang.org/x/crypto/bcrypt"
 )
 
 const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
@@ -48,7 +48,7 @@ type Node struct {
 	ExpirationDateTime  int64    `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"`
 	LastPeerUpdate      int64    `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"`
 	LastCheckIn         int64    `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"`
-	MacAddress          string   `json:"macaddress" bson:"macaddress" yaml:"macaddress" validate:"required,mac,macaddress_unique"`
+	MacAddress          string   `json:"macaddress" bson:"macaddress" yaml:"macaddress" validate:"required,min=5,macaddress_unique"`
 	// checkin interval is depreciated at the network level. Set on server with CHECKIN_INTERVAL
 	CheckInInterval     int32    `json:"checkininterval" bson:"checkininterval" yaml:"checkininterval"`
 	Password            string   `json:"password" bson:"password" yaml:"password" validate:"required,min=6"`

+ 16 - 0
models/structs.go

@@ -2,11 +2,13 @@ package models
 
 import jwt "github.com/golang-jwt/jwt/v4"
 
+// AuthParams - struct for auth params
 type AuthParams struct {
 	MacAddress string `json:"macaddress"`
 	Password   string `json:"password"`
 }
 
+// User struct - struct for Users
 type User struct {
 	UserName string   `json:"username" bson:"username" validate:"min=3,max=40,regexp=^(([a-zA-Z,\-,\.]*)|([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})){3,40}$"`
 	Password string   `json:"password" bson:"password" validate:"required,min=5"`
@@ -14,17 +16,20 @@ type User struct {
 	IsAdmin  bool     `json:"isadmin" bson:"isadmin"`
 }
 
+// ReturnUser - return user struct
 type ReturnUser struct {
 	UserName string   `json:"username" bson:"username" validate:"min=3,max=40,regexp=^(([a-zA-Z,\-,\.]*)|([A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4})){3,40}$"`
 	Networks []string `json:"networks" bson:"networks"`
 	IsAdmin  bool     `json:"isadmin" bson:"isadmin"`
 }
 
+// UserAuthParams - user auth params struct
 type UserAuthParams struct {
 	UserName string `json:"username"`
 	Password string `json:"password"`
 }
 
+// UserClaims - user claims struct
 type UserClaims struct {
 	IsAdmin  bool
 	UserName string
@@ -32,6 +37,7 @@ type UserClaims struct {
 	jwt.StandardClaims
 }
 
+// SuccessfulUserLoginResponse - successlogin struct
 type SuccessfulUserLoginResponse struct {
 	UserName  string
 	AuthToken string
@@ -51,11 +57,13 @@ type SuccessfulLoginResponse struct {
 	AuthToken  string
 }
 
+// ErrorResponse is struct for error
 type ErrorResponse struct {
 	Code    int
 	Message string
 }
 
+// NodeAuth - struct for node auth
 type NodeAuth struct {
 	Network    string
 	Password   string
@@ -69,6 +77,7 @@ type SuccessResponse struct {
 	Response interface{}
 }
 
+// AccessKey - access key struct
 type AccessKey struct {
 	Name         string `json:"name" bson:"name" validate:"omitempty,max=20"`
 	Value        string `json:"value" bson:"value" validate:"omitempty,alphanum,max=16"`
@@ -76,17 +85,20 @@ type AccessKey struct {
 	Uses         int    `json:"uses" bson:"uses"`
 }
 
+// DisplayKey - what is displayed for key
 type DisplayKey struct {
 	Name string `json:"name" bson:"name"`
 	Uses int    `json:"uses" bson:"uses"`
 }
 
+// GlobalConfig - global config
 type GlobalConfig struct {
 	Name       string `json:"name" bson:"name"`
 	PortGRPC   string `json:"portgrpc" bson:"portgrpc"`
 	ServerGRPC string `json:"servergrpc" bson:"servergrpc"`
 }
 
+// CheckInResponse - checkin response
 type CheckInResponse struct {
 	Success          bool   `json:"success" bson:"success"`
 	NeedPeerUpdate   bool   `json:"needpeerupdate" bson:"needpeerupdate"`
@@ -97,6 +109,7 @@ type CheckInResponse struct {
 	IsPending        bool   `json:"ispending" bson:"ispending"`
 }
 
+// PeersResponse - peers response
 type PeersResponse struct {
 	PublicKey           string `json:"publickey" bson:"publickey"`
 	Endpoint            string `json:"endpoint" bson:"endpoint"`
@@ -109,6 +122,7 @@ type PeersResponse struct {
 	KeepAlive           int32  `json:"persistentkeepalive" bson:"persistentkeepalive"`
 }
 
+// ExtPeersResponse - ext peers response
 type ExtPeersResponse struct {
 	PublicKey    string `json:"publickey" bson:"publickey"`
 	Endpoint     string `json:"endpoint" bson:"endpoint"`
@@ -119,6 +133,7 @@ type ExtPeersResponse struct {
 	KeepAlive    int32  `json:"persistentkeepalive" bson:"persistentkeepalive"`
 }
 
+// EgressGatewayRequest - egress gateway request
 type EgressGatewayRequest struct {
 	NodeID      string   `json:"nodeid" bson:"nodeid"`
 	NetID       string   `json:"netid" bson:"netid"`
@@ -129,6 +144,7 @@ type EgressGatewayRequest struct {
 	PostDown    string   `json:"postdown" bson:"postdown"`
 }
 
+// RelayRequest - relay request struct
 type RelayRequest struct {
 	NodeID     string   `json:"nodeid" bson:"nodeid"`
 	NetID      string   `json:"netid" bson:"netid"`

+ 2 - 0
models/validation.go

@@ -6,10 +6,12 @@ import (
 	"github.com/go-playground/validator/v10"
 )
 
+// CheckYesOrNo - checks if a field on a struct is yes or no
 func CheckYesOrNo(fl validator.FieldLevel) bool {
 	return fl.Field().String() == "yes" || fl.Field().String() == "no"
 }
 
+// CheckRegex - check if a struct's field passes regex test
 func CheckRegex(fl validator.FieldLevel) bool {
 	re := regexp.MustCompile(fl.Param())
 	return re.MatchString(fl.Field().String())

+ 5 - 1
netclient/auth/auth.go

@@ -18,7 +18,7 @@ import (
 	"google.golang.org/grpc/status"
 )
 
-// CreateJWT func will used to create the JWT while signing in and signing out
+// SetJWT func will used to create the JWT while signing in and signing out
 func SetJWT(client nodepb.NodeServiceClient, network string) (context.Context, error) {
 	home := ncutils.GetNetclientPathSpecific()
 	tokentext, err := ioutil.ReadFile(home + "nettoken-" + network)
@@ -41,6 +41,7 @@ func SetJWT(client nodepb.NodeServiceClient, network string) (context.Context, e
 	return ctx, nil
 }
 
+// AutoLogin - auto logins whenever client needs to request from server
 func AutoLogin(client nodepb.NodeServiceClient, network string) error {
 	home := ncutils.GetNetclientPathSpecific()
 	cfg, err := config.ReadConfig(network)
@@ -77,17 +78,20 @@ func AutoLogin(client nodepb.NodeServiceClient, network string) error {
 	return err
 }
 
+// StoreSecret - stores auth secret locally
 func StoreSecret(key string, network string) error {
 	d1 := []byte(key)
 	err := ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"secret-"+network, d1, 0644)
 	return err
 }
 
+// RetrieveSecret - fetches secret locally
 func RetrieveSecret(network string) (string, error) {
 	dat, err := ioutil.ReadFile(ncutils.GetNetclientPathSpecific() + "secret-" + network)
 	return string(dat), err
 }
 
+// Configuraion - struct for mac and pass
 type Configuration struct {
 	MacAddress string
 	Password   string

+ 20 - 9
netclient/config/config.go

@@ -15,11 +15,13 @@ import (
 	"gopkg.in/yaml.v3"
 )
 
+// GlobalConfig - struct for handling IntClients currently
 type GlobalConfig struct {
 	GRPCWireGuard string `yaml:"grpcwg"`
 	Client        models.IntClient
 }
 
+// ClientConfig - struct for dealing with client configuration
 type ClientConfig struct {
 	Server          ServerConfig `yaml:"server"`
 	Node            models.Node  `yaml:"node"`
@@ -28,23 +30,25 @@ type ClientConfig struct {
 	OperatingSystem string       `yaml:"operatingsystem"`
 	DebugJoin       bool         `yaml:"debugjoin"`
 }
+
+// ServerConfig - struct for dealing with the server information for a netclient
 type ServerConfig struct {
-	CoreDNSAddr   string `yaml:"corednsaddr"`
-	GRPCAddress   string `yaml:"grpcaddress"`
-	APIAddress    string `yaml:"apiaddress"`
-	AccessKey     string `yaml:"accesskey"`
-	GRPCSSL       string `yaml:"grpcssl"`
-	GRPCWireGuard string `yaml:"grpcwg"`
+	CoreDNSAddr     string `yaml:"corednsaddr"`
+	GRPCAddress     string `yaml:"grpcaddress"`
+	APIAddress      string `yaml:"apiaddress"`
+	AccessKey       string `yaml:"accesskey"`
+	GRPCSSL         string `yaml:"grpcssl"`
+	GRPCWireGuard   string `yaml:"grpcwg"`
 	CheckinInterval string `yaml:"checkininterval"`
 }
 
-//reading in the env file
+// Write - writes the config of a client to disk
 func Write(config *ClientConfig, network string) error {
 	if network == "" {
 		err := errors.New("no network provided - exiting")
 		return err
 	}
-	_, err := os.Stat(ncutils.GetNetclientPath()+"/config")
+	_, err := os.Stat(ncutils.GetNetclientPath() + "/config")
 	if os.IsNotExist(err) {
 		os.MkdirAll(ncutils.GetNetclientPath()+"/config", 0744)
 	} else if err != nil {
@@ -66,6 +70,7 @@ func Write(config *ClientConfig, network string) error {
 	return err
 }
 
+// WriteServer - writes the config of a server to disk for client
 func WriteServer(server string, accesskey string, network string) error {
 	if network == "" {
 		err := errors.New("no network provided - exiting")
@@ -73,7 +78,7 @@ func WriteServer(server string, accesskey string, network string) error {
 	}
 	nofile := false
 	//home, err := homedir.Dir()
-	_, err := os.Stat(ncutils.GetNetclientPath()+"/config")
+	_, err := os.Stat(ncutils.GetNetclientPath() + "/config")
 	if os.IsNotExist(err) {
 		os.MkdirAll(ncutils.GetNetclientPath()+"/config", 0744)
 	} else if err != nil {
@@ -149,6 +154,7 @@ func WriteServer(server string, accesskey string, network string) error {
 	return err
 }
 
+// ClientConfig.ReadConfig - used to read config from client disk into memory
 func (config *ClientConfig) ReadConfig() {
 
 	nofile := false
@@ -181,6 +187,7 @@ func (config *ClientConfig) ReadConfig() {
 	}
 }
 
+// ModConfig - overwrites the node inside client config on disk
 func ModConfig(node *models.Node) error {
 	network := node.Network
 	if network == "" {
@@ -201,6 +208,7 @@ func ModConfig(node *models.Node) error {
 	return err
 }
 
+// GetCLIConfig - gets the cli flags as a config
 func GetCLIConfig(c *cli.Context) (ClientConfig, string, error) {
 	var cfg ClientConfig
 	if c.String("token") != "" {
@@ -312,6 +320,7 @@ func GetCLIConfig(c *cli.Context) (ClientConfig, string, error) {
 	return cfg, privateKey, nil
 }
 
+// ReadConfig - reads a config of a client from disk for specified network
 func ReadConfig(network string) (*ClientConfig, error) {
 	if network == "" {
 		err := errors.New("no network provided - exiting")
@@ -340,6 +349,7 @@ func ReadConfig(network string) (*ClientConfig, error) {
 	return &cfg, err
 }
 
+// FileExists - checks if a file exists on disk
 func FileExists(f string) bool {
 	info, err := os.Stat(f)
 	if os.IsNotExist(err) {
@@ -348,6 +358,7 @@ func FileExists(f string) bool {
 	return !info.IsDir()
 }
 
+// GetNode - parses a network specified client config for node data
 func GetNode(network string) models.Node {
 
 	modcfg, err := ReadConfig(network)

+ 3 - 3
netclient/daemon/macos.go

@@ -1,12 +1,12 @@
 package daemon
 
 import (
+	"fmt"
+	"github.com/gravitl/netmaker/netclient/ncutils"
 	"io/ioutil"
 	"log"
 	"os"
-	"fmt"
 	"path/filepath"
-	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 
 const MAC_SERVICE_NAME = "com.gravitl.netclient"
@@ -93,7 +93,7 @@ func MacDaemonString(interval string) string {
 		</dict>
 </dict>
 </plist>
-`,interval)
+`, interval)
 }
 
 type MacTemplateData struct {

+ 3 - 2
netclient/daemon/systemd.go

@@ -11,8 +11,9 @@ import (
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 
+// SetupSystemDDaemon - sets system daemon for supported machines
 func SetupSystemDDaemon(interval string) error {
-	
+
 	if ncutils.IsWindows() {
 		return nil
 	}
@@ -96,6 +97,7 @@ WantedBy=timers.target
 	return nil
 }
 
+// RemoveSystemDServices - removes the systemd services on a machine
 func RemoveSystemDServices(network string) error {
 	//sysExec, err := exec.LookPath("systemctl")
 	if !ncutils.IsWindows() {
@@ -130,7 +132,6 @@ func RemoveSystemDServices(network string) error {
 	return nil
 }
 
-
 func isOnlyService(network string) (bool, error) {
 	isonly := false
 	files, err := filepath.Glob("/etc/netclient/config/netconfig-*")

+ 5 - 0
netclient/daemon/windows.go

@@ -12,6 +12,7 @@ import (
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 
+// SetupWindowsDaemon - sets up the Windows daemon service
 func SetupWindowsDaemon() error {
 
 	if !ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "winsw.xml") {
@@ -42,6 +43,7 @@ func SetupWindowsDaemon() error {
 	return nil
 }
 
+// CleanupWindows - cleans up windows files
 func CleanupWindows() {
 	if !ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "winsw.xml") {
 		writeServiceConfig()
@@ -73,12 +75,15 @@ func writeServiceConfig() error {
 }
 
 // == Daemon ==
+
+// StopWindowsDaemon - stops the Windows daemon
 func StopWindowsDaemon() {
 	ncutils.Log("no networks detected, stopping Windows, Netclient daemon")
 	// stop daemon, will not overwrite
 	ncutils.RunCmd(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe stop`, true)
 }
 
+// RemoveWindowsDaemon - removes the Windows daemon
 func RemoveWindowsDaemon() {
 	// uninstall daemon, will not restart or start another
 	ncutils.RunCmd(strings.Replace(ncutils.GetNetclientPathSpecific(), `\\`, `\`, -1)+`winsw.exe uninstall`, true)

+ 3 - 4
netclient/functions/checkin.go

@@ -111,6 +111,7 @@ func checkNodeActions(node *models.Node, networkName string, servercfg config.Se
 	return ""
 }
 
+// CheckConfig - checks if current config of client needs update, see flow below
 /**
  * Pull changes if any (interface refresh)
  * - Save it
@@ -148,10 +149,7 @@ func CheckConfig(cliconf config.ClientConfig) error {
 	return Push(network)
 }
 
-/**
- * Pull the latest node from server
- * Perform action if necessary
- */
+// Pull - pulls the latest config from the server, if manual it will overwrite
 func Pull(network string, manual bool) (*models.Node, error) {
 	cfg, err := config.ReadConfig(network)
 	node := cfg.Node
@@ -259,6 +257,7 @@ func Pull(network string, manual bool) (*models.Node, error) {
 	return &resNode, err
 }
 
+// Push - pushes current client configuration to server
 func Push(network string) error {
 	cfg, err := config.ReadConfig(network)
 	if err != nil {

+ 8 - 0
netclient/functions/common.go

@@ -28,6 +28,7 @@ var (
 	wcclient nodepb.NodeServiceClient
 )
 
+// ListPorts - lists ports of WireGuard devices
 func ListPorts() error {
 	wgclient, err := wgctrl.New()
 	if err != nil {
@@ -127,6 +128,7 @@ func needInterfaceUpdate(ctx context.Context, mac string, network string, iface
 	return iface != oldiface, oldiface, err
 }
 
+// GetNode - gets node locally
 func GetNode(network string) models.Node {
 
 	modcfg, err := config.ReadConfig(network)
@@ -137,6 +139,7 @@ func GetNode(network string) models.Node {
 	return modcfg.Node
 }
 
+// Uninstall - uninstalls networks from client
 func Uninstall() error {
 	networks, err := ncutils.GetSystemNetworks()
 	if err != nil {
@@ -162,6 +165,7 @@ func Uninstall() error {
 	return err
 }
 
+// LeaveNetwork - client exits a network
 func LeaveNetwork(network string) error {
 	cfg, err := config.ReadConfig(network)
 	if err != nil {
@@ -211,6 +215,7 @@ func LeaveNetwork(network string) error {
 	return RemoveLocalInstance(cfg, network)
 }
 
+// RemoveLocalInstance - remove all netclient files locally for a network
 func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
 	err := WipeLocal(networkName)
 	if err != nil {
@@ -230,6 +235,7 @@ func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
 	return err
 }
 
+// DeleteInterface - delete an interface of a network
 func DeleteInterface(ifacename string, postdown string) error {
 	var err error
 	if !ncutils.IsKernel() {
@@ -249,6 +255,7 @@ func DeleteInterface(ifacename string, postdown string) error {
 	return err
 }
 
+// List - lists all networks on local machine
 func List() error {
 
 	networks, err := ncutils.GetSystemNetworks()
@@ -274,6 +281,7 @@ func List() error {
 	return nil
 }
 
+// WipeLocal - wipes local instance
 func WipeLocal(network string) error {
 	cfg, err := config.ReadConfig(network)
 	if err != nil {

+ 1 - 0
netclient/functions/join.go

@@ -21,6 +21,7 @@ import (
 	"google.golang.org/grpc"
 )
 
+// JoinNetwork - helps a client join a network
 func JoinNetwork(cfg config.ClientConfig, privateKey string) error {
 
 	hasnet := local.HasNetwork(cfg.Network)

+ 2 - 0
netclient/local/dns.go

@@ -12,6 +12,7 @@ import (
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 
+// SetDNS - sets the DNS of a local machine
 func SetDNS(nameserver string) error {
 	bytes, err := ioutil.ReadFile("/etc/resolv.conf")
 	if err != nil {
@@ -33,6 +34,7 @@ func SetDNS(nameserver string) error {
 	return err
 }
 
+// UpdateDNS - updates local DNS of client
 func UpdateDNS(ifacename string, network string, nameserver string) error {
 	if ncutils.IsWindows() {
 		return nil

+ 10 - 3
netclient/local/local.go

@@ -5,13 +5,15 @@ import (
 	"errors"
 	"log"
 	"net"
+	"os"
+	"os/exec"
 	"runtime"
 	"strings"
-	"os/exec"
-	"os"
+
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 
+// SetIPForwarding - Sets IP forwarding if it's mac or linux
 func SetIPForwarding() error {
 	os := runtime.GOOS
 	var err error
@@ -26,6 +28,7 @@ func SetIPForwarding() error {
 	return err
 }
 
+// SetIPForwardingLinux - sets the ipforwarding for linux
 func SetIPForwardingLinux() error {
 	out, err := ncutils.RunCmd("sysctl net.ipv4.ip_forward", true)
 	if err != nil {
@@ -44,6 +47,7 @@ func SetIPForwardingLinux() error {
 	return nil
 }
 
+// SetIPForwardingMac - sets ip forwarding for mac
 func SetIPForwardingMac() error {
 	_, err := ncutils.RunCmd("sysctl -w net.inet.ip.forwarding=1", true)
 	if err != nil {
@@ -52,6 +56,7 @@ func SetIPForwardingMac() error {
 	return err
 }
 
+// IsWGInstalled - checks if WireGuard is installed
 func IsWGInstalled() bool {
 	out, err := ncutils.RunCmd("wg help", true)
 	if err != nil {
@@ -61,6 +66,7 @@ func IsWGInstalled() bool {
 	return strings.Contains(out, "Available subcommand")
 }
 
+// GetMacIface - gets mac interface
 func GetMacIface(ipstring string) (string, error) {
 	var wgiface string
 	_, checknet, err := net.ParseCIDR(ipstring + "/24")
@@ -90,6 +96,7 @@ func GetMacIface(ipstring string) (string, error) {
 	return wgiface, err
 }
 
+// HasNetwork - checks if a network exists locally
 func HasNetwork(network string) bool {
-		return ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "netconfig-" + network)
+	return ncutils.FileExists(ncutils.GetNetclientPathSpecific() + "netconfig-" + network)
 }

+ 38 - 3
netclient/ncutils/netclientutils.go

@@ -23,31 +23,49 @@ import (
 	"google.golang.org/grpc/credentials"
 )
 
+// NO_DB_RECORD - error message result
 const NO_DB_RECORD = "no result found"
+
+// NO_DB_RECORDS - error record result
 const NO_DB_RECORDS = "could not find any records"
+
+// LINUX_APP_DATA_PATH - linux path
 const LINUX_APP_DATA_PATH = "/etc/netclient"
+
+// WINDOWS_APP_DATA_PATH - windows path
 const WINDOWS_APP_DATA_PATH = "C:\\ProgramData\\Netclient"
+
+// WINDOWS_SVC_NAME - service name
 const WINDOWS_SVC_NAME = "netclient"
+
+// NETCLIENT_DEFAULT_PORT - default port
 const NETCLIENT_DEFAULT_PORT = 51821
+
+// DEFAULT_GC_PERCENT - garbage collection percent
 const DEFAULT_GC_PERCENT = 10
 
+// Log - logs a message
 func Log(message string) {
 	log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
 	log.Println("[netclient]", message)
 }
 
+// IsWindows - checks if is windows
 func IsWindows() bool {
 	return runtime.GOOS == "windows"
 }
 
+// IsMac - checks if is a mac
 func IsMac() bool {
 	return runtime.GOOS == "darwin"
 }
 
+// IsLinux - checks if is linux
 func IsLinux() bool {
 	return runtime.GOOS == "linux"
 }
 
+// GetWireGuard - checks if wg is installed
 func GetWireGuard() string {
 	userspace := os.Getenv("WG_QUICK_USERSPACE_IMPLEMENTATION")
 	if userspace != "" && (userspace == "boringtun" || userspace == "wireguard-go") {
@@ -56,6 +74,7 @@ func GetWireGuard() string {
 	return "wg"
 }
 
+// IsKernel - checks if running kernel WireGuard
 func IsKernel() bool {
 	//TODO
 	//Replace && true with some config file value
@@ -63,7 +82,7 @@ func IsKernel() bool {
 	return IsLinux() && os.Getenv("WG_QUICK_USERSPACE_IMPLEMENTATION") == ""
 }
 
-// == database returned nothing error ==
+// IsEmptyRecord - repeat from database
 func IsEmptyRecord(err error) bool {
 	if err == nil {
 		return false
@@ -72,6 +91,7 @@ func IsEmptyRecord(err error) bool {
 }
 
 //generate an access key value
+// GenPass - generates a pass
 func GenPass() string {
 
 	var seededRand *rand.Rand = rand.New(
@@ -87,6 +107,7 @@ func GenPass() string {
 	return string(b)
 }
 
+// GetPublicIP - gets public ip
 func GetPublicIP() (string, error) {
 
 	iplist := []string{"http://ip.client.gravitl.com", "https://ifconfig.me", "http://api.ipify.org", "http://ipinfo.io/ip"}
@@ -113,6 +134,7 @@ func GetPublicIP() (string, error) {
 	return endpoint, err
 }
 
+// GetMacAddr - get's mac address
 func GetMacAddr() ([]string, error) {
 	ifas, err := net.Interfaces()
 	if err != nil {
@@ -154,6 +176,7 @@ PersistentKeepAlive = %s
 	return peersString, nil
 }
 
+// CreateUserSpaceConf - creates a user space WireGuard conf
 func CreateUserSpaceConf(address string, privatekey string, listenPort string, mtu int32, perskeepalive int32, peers []wgtypes.PeerConfig) (string, error) {
 	peersString, err := parsePeers(perskeepalive, peers)
 	listenPortString := ""
@@ -183,6 +206,7 @@ MTU = %s
 	return config, nil
 }
 
+// GetLocalIP - gets local ip of machine
 func GetLocalIP(localrange string) (string, error) {
 	_, localRange, err := net.ParseCIDR(localrange)
 	if err != nil {
@@ -229,6 +253,7 @@ func GetLocalIP(localrange string) (string, error) {
 	return local, nil
 }
 
+// GetFreePort - gets free port of machine
 func GetFreePort(rangestart int32) (int32, error) {
 	if rangestart == 0 {
 		rangestart = NETCLIENT_DEFAULT_PORT
@@ -259,6 +284,7 @@ func GetFreePort(rangestart int32) (int32, error) {
 
 // == OS PATH FUNCTIONS ==
 
+// GetHomeDirWindows - gets home directory in windows
 func GetHomeDirWindows() string {
 	if IsWindows() {
 		home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
@@ -270,6 +296,7 @@ func GetHomeDirWindows() string {
 	return os.Getenv("HOME")
 }
 
+// GetNetclientPath - gets netclient path locally
 func GetNetclientPath() string {
 	if IsWindows() {
 		return WINDOWS_APP_DATA_PATH
@@ -280,6 +307,7 @@ func GetNetclientPath() string {
 	}
 }
 
+// GetNetclientPathSpecific - gets specific netclient config path
 func GetNetclientPathSpecific() string {
 	if IsWindows() {
 		return WINDOWS_APP_DATA_PATH + "\\"
@@ -290,6 +318,7 @@ func GetNetclientPathSpecific() string {
 	}
 }
 
+// GRPCRequestOpts - gets grps request opts
 func GRPCRequestOpts(isSecure string) grpc.DialOption {
 	var requestOpts grpc.DialOption
 	requestOpts = grpc.WithInsecure()
@@ -300,6 +329,7 @@ func GRPCRequestOpts(isSecure string) grpc.DialOption {
 	return requestOpts
 }
 
+// Copy - copies a src file to dest
 func Copy(src, dst string) (int64, error) {
 	sourceFileStat, err := os.Stat(src)
 	if err != nil {
@@ -329,6 +359,7 @@ func Copy(src, dst string) (int64, error) {
 	return nBytes, err
 }
 
+// RunCmd - runs a local command
 func RunCmd(command string, printerr bool) (string, error) {
 	args := strings.Fields(command)
 	cmd := exec.Command(args[0], args[1:]...)
@@ -341,6 +372,7 @@ func RunCmd(command string, printerr bool) (string, error) {
 	return string(out), err
 }
 
+// RunsCmds - runs cmds
 func RunCmds(commands []string, printerr bool) error {
 	var err error
 	for _, command := range commands {
@@ -354,6 +386,7 @@ func RunCmds(commands []string, printerr bool) error {
 	return err
 }
 
+// FileExists - checks if file exists locally
 func FileExists(f string) bool {
 	info, err := os.Stat(f)
 	if os.IsNotExist(err) {
@@ -362,6 +395,7 @@ func FileExists(f string) bool {
 	return !info.IsDir()
 }
 
+// PrintLog - prints log
 func PrintLog(message string, loglevel int) {
 	log.SetFlags(log.Flags() &^ (log.Llongfile | log.Lshortfile))
 	if loglevel < 2 {
@@ -369,6 +403,7 @@ func PrintLog(message string, loglevel int) {
 	}
 }
 
+// GetSystemNetworks - get networks locally
 func GetSystemNetworks() ([]string, error) {
 	var networks []string
 	files, err := ioutil.ReadDir(GetNetclientPathSpecific())
@@ -394,5 +429,5 @@ func stringAfter(original string, substring string) string {
 	if adjustedPosition >= len(original) {
 		return ""
 	}
-	return original[adjustedPosition:len(original)]
-}
+	return original[adjustedPosition:]
+}

+ 1 - 1
netclient/ncwindows/windows.go

@@ -8,7 +8,7 @@ import (
 	"github.com/gravitl/netmaker/netclient/ncutils"
 )
 
-// Initialize windows directory & files and such
+// InitWindows - Initialize windows directory & files and such
 func InitWindows() {
 
 	_, directoryErr := os.Stat(ncutils.GetNetclientPath()) // Check if data directory exists or not

+ 6 - 1
netclient/server/grpc.go

@@ -19,6 +19,7 @@ import (
 	"google.golang.org/grpc/metadata"
 )
 
+// RELAY_KEEPALIVE_MARKER - sets the relay keepalive marker
 const RELAY_KEEPALIVE_MARKER = "20007ms"
 
 func getGrpcClient(cfg *config.ClientConfig) (nodepb.NodeServiceClient, error) {
@@ -35,6 +36,7 @@ func getGrpcClient(cfg *config.ClientConfig) (nodepb.NodeServiceClient, error) {
 	return wcclient, nil
 }
 
+// CheckIn - checkin for node on a network
 func CheckIn(network string) (*models.Node, error) {
 	cfg, err := config.ReadConfig(network)
 	if err != nil {
@@ -120,6 +122,7 @@ func RemoveNetwork(network string) error {
 }
 */
 
+// GetPeers - gets the peers for a node
 func GetPeers(macaddress string, network string, server string, dualstack bool, isIngressGateway bool, isServer bool) ([]wgtypes.PeerConfig, bool, []string, error) {
 	hasGateway := false
 	var gateways []string
@@ -251,7 +254,7 @@ func GetPeers(macaddress string, network string, server string, dualstack bool,
 			}
 			allowedips = append(allowedips, addr6)
 		}
-		if nodecfg.IsServer == "yes" && !(node.IsServer == "yes"){
+		if nodecfg.IsServer == "yes" && !(node.IsServer == "yes") {
 			peer = wgtypes.PeerConfig{
 				PublicKey:                   pubkey,
 				PersistentKeepaliveInterval: &keepaliveserver,
@@ -292,6 +295,8 @@ func GetPeers(macaddress string, network string, server string, dualstack bool,
 	}
 	return peers, hasGateway, gateways, err
 }
+
+// GetExtPeers - gets the extpeers for a client
 func GetExtPeers(macaddress string, network string, server string, dualstack bool) ([]wgtypes.PeerConfig, error) {
 	var peers []wgtypes.PeerConfig
 

+ 5 - 1
netclient/wireguard/common.go

@@ -18,9 +18,9 @@ import (
 	"github.com/gravitl/netmaker/netclient/server"
 	"golang.zx2c4.com/wireguard/wgctrl"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
-	//homedir "github.com/mitchellh/go-homedir"
 )
 
+// SetPeers - sets peers on a given WireGuard interface
 func SetPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) error {
 
 	client, err := wgctrl.New()
@@ -95,6 +95,7 @@ func SetPeers(iface string, keepalive int32, peers []wgtypes.PeerConfig) error {
 	return nil
 }
 
+// Initializes a WireGuard interface
 func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig, hasGateway bool, gateways []string) error {
 
 	key, err := wgtypes.ParseKey(privkey)
@@ -258,6 +259,7 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 	return err
 }
 
+// SetWGConfig - sets the WireGuard Config of a given network and checks if it needs a peer update
 func SetWGConfig(network string, peerupdate bool) error {
 
 	cfg, err := config.ReadConfig(network)
@@ -291,6 +293,7 @@ func SetWGConfig(network string, peerupdate bool) error {
 	return err
 }
 
+// RemoveConf - removes a configuration for a given WireGuard interface
 func RemoveConf(iface string, printlog bool) error {
 	os := runtime.GOOS
 	var err error
@@ -304,6 +307,7 @@ func RemoveConf(iface string, printlog bool) error {
 	return err
 }
 
+// ApplyConf - applys a conf on disk to WireGuard interface
 func ApplyConf(confPath string) error {
 	os := runtime.GOOS
 	var err error

+ 5 - 1
netclient/wireguard/unix.go

@@ -7,9 +7,9 @@ import (
 	"github.com/gravitl/netmaker/netclient/config"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
-	//homedir "github.com/mitchellh/go-homedir"
 )
 
+// SetWGKeyConfig - sets the wg conf with a new private key
 func SetWGKeyConfig(network string, serveraddr string) error {
 
 	cfg, err := config.ReadConfig(network)
@@ -48,6 +48,7 @@ func SetWGKeyConfig(network string, serveraddr string) error {
 	return err
 }
 
+// ApplyWGQuickConf - applies wg-quick commands if os supports
 func ApplyWGQuickConf(confPath string) error {
 	if _, err := ncutils.RunCmd("wg-quick up "+confPath, true); err != nil {
 		return err
@@ -55,6 +56,7 @@ func ApplyWGQuickConf(confPath string) error {
 	return nil
 }
 
+// RemoveWGQuickConf - calls wg-quick down
 func RemoveWGQuickConf(confPath string, printlog bool) error {
 	if _, err := ncutils.RunCmd("wg-quick down "+confPath, printlog); err != nil {
 		return err
@@ -62,12 +64,14 @@ func RemoveWGQuickConf(confPath string, printlog bool) error {
 	return nil
 }
 
+// StorePrivKey - stores wg priv key on disk locally
 func StorePrivKey(key string, network string) error {
 	d1 := []byte(key)
 	err := ioutil.WriteFile(ncutils.GetNetclientPathSpecific()+"wgkey-"+network, d1, 0644)
 	return err
 }
 
+// RetrievePrivKey - reads wg priv key from local disk
 func RetrievePrivKey(network string) (string, error) {
 	dat, err := ioutil.ReadFile(ncutils.GetNetclientPathSpecific() + "wgkey-" + network)
 	return string(dat), err

+ 1 - 0
relay/relay.go

@@ -9,6 +9,7 @@ import (
 	"github.com/gravitl/netmaker/models"
 )
 
+// GetNodeRelay - gets the relay node of a given network
 func GetNodeRelay(network string, relayedNodeAddr string) (models.Node, error) {
 	collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
 	var relay models.Node

+ 31 - 3
servercfg/serverconf.go

@@ -4,9 +4,9 @@ import (
 	"errors"
 	"io/ioutil"
 	"net/http"
+	"net"
 	"os"
 	"strconv"
-
 	"github.com/gravitl/netmaker/config"
 )
 
@@ -31,6 +31,7 @@ func GetServerConfig() config.ServerConfig {
 	cfg.AllowedOrigin = GetAllowedOrigin()
 	cfg.RestBackend = "off"
 	cfg.Verbosity = GetVerbose()
+	cfg.NodeID = GetNodeID()
 	cfg.CheckinInterval = GetCheckinInterval()
 	if IsRestBackend() {
 		cfg.RestBackend = "on"
@@ -82,9 +83,9 @@ func GetVersion() string {
 }
 func GetDB() string {
 	database := "sqlite"
-	if os.Getenv("DATABASE") == "rqlite" {
+	if os.Getenv("DATABASE") != "" {
 		database = os.Getenv("DATABASE")
-	} else if config.Config.Server.Database == "rqlite" {
+	} else if config.Config.Server.Database != "" {
 		database = config.Config.Server.Database
 	}
 	return database
@@ -372,3 +373,30 @@ func IsSplitDNS() bool {
 	}
 	return issplit
 }
+
+func GetNodeID() string {
+	var id string
+	id = getMacAddr()
+	if os.Getenv("NODE_ID") != "" {
+		id = os.Getenv("NODE_ID")
+	} else if config.Config.Server.NodeID != "" {
+		id = config.Config.Server.NodeID
+	}
+	return id
+}
+
+// GetMacAddr - get's mac address
+func getMacAddr() string {
+	ifas, err := net.Interfaces()
+	if err != nil {
+		return ""
+	}
+	var as []string
+	for _, ifa := range ifas {
+		a := ifa.HardwareAddr.String()
+		if a != "" {
+			as = append(as, a)
+		}
+	}
+	return as[0]
+}

+ 73 - 0
servercfg/sqlconf.go

@@ -0,0 +1,73 @@
+package servercfg
+
+import (
+	"os"
+	"github.com/gravitl/netmaker/config"
+	"strconv"
+)
+
+func GetSQLConf() config.SQLConfig {
+	var cfg config.SQLConfig
+	cfg.Host = GetSQLHost()
+	cfg.Port = GetSQLPort()
+	cfg.Username = GetSQLUser()
+	cfg.Password = GetSQLPass()
+	cfg.DB = GetSQLDB()
+	cfg.SSLMode = GetSQLSSLMode()
+	return cfg
+}
+func GetSQLHost() string {
+	host := "localhost"
+	if os.Getenv("SQL_HOST") != "" {
+		host = os.Getenv("SQL_HOST")
+	} else if config.Config.SQL.Host != "" {
+		host = config.Config.SQL.Host
+	}
+	return host
+}
+func GetSQLPort() int32 {
+	port := int32(5432)
+	envport, err := strconv.Atoi(os.Getenv("SQL_PORT"))
+	if err == nil && envport != 0 {
+		port = int32(envport)
+	} else if config.Config.SQL.Port != 0 {
+		port = config.Config.SQL.Port
+	}
+	return port
+}
+func GetSQLUser() string {
+	user := "posgres"
+	if os.Getenv("SQL_USER") != "" {
+		user = os.Getenv("SQL_USER")
+	} else if config.Config.SQL.Username != "" {
+		user = config.Config.SQL.Username
+	}
+	return user
+}
+func GetSQLPass() string {
+	pass := "nopass"
+	if os.Getenv("SQL_PASS") != "" {
+		pass = os.Getenv("SQL_PASS")
+	} else if config.Config.SQL.Password != "" {
+		pass = config.Config.SQL.Password
+	}
+	return pass
+}
+func GetSQLDB() string {
+	db := "netmaker"
+	if os.Getenv("SQL_DB") != "" {
+		db = os.Getenv("SQL_DB")
+	} else if config.Config.SQL.DB != "" {
+		db = config.Config.SQL.DB
+	}
+	return db
+}
+func GetSQLSSLMode() string {
+	sslmode := "disable"
+	if os.Getenv("SQL_SSL_MODE") != "" {
+		sslmode = os.Getenv("SQL_SSL_MODE")
+	} else if config.Config.SQL.SSLMode != "" {
+		sslmode = config.Config.SQL.SSLMode
+	}
+	return sslmode
+}

+ 9 - 0
serverctl/serverctl.go

@@ -15,6 +15,7 @@ import (
 	"github.com/gravitl/netmaker/servercfg"
 )
 
+// GetServerWGConf - gets the server WG configuration
 func GetServerWGConf() (models.IntClient, error) {
 	var server models.IntClient
 	collection, err := database.FetchRecords(database.INT_CLIENTS_TABLE_NAME)
@@ -30,6 +31,7 @@ func GetServerWGConf() (models.IntClient, error) {
 	return models.IntClient{}, errors.New("could not find comms server")
 }
 
+// InstallNetclient netclient installation for server - depricated
 func InstallNetclient() error {
 
 	netclientPath := ncutils.GetNetclientPath()
@@ -53,6 +55,7 @@ func InstallNetclient() error {
 	return nil
 }
 
+// FileExists - checks if local file exists
 func FileExists(f string) bool {
 	info, err := os.Stat(f)
 	if os.IsNotExist(err) {
@@ -90,11 +93,13 @@ func copy(src, dst string) (int64, error) {
 	return nBytes, err
 }
 
+// RemoveNetwork - removes a network locally on server
 func RemoveNetwork(network string) (bool, error) {
 	err := nccommand.Leave(config.ClientConfig{Network: network})
 	return true, err
 }
 
+// InitServerNetclient - intializes the server netclient
 func InitServerNetclient() error {
 	netclientDir := ncutils.GetNetclientPath()
 	_, err := os.Stat(netclientDir + "/config")
@@ -107,6 +112,7 @@ func InitServerNetclient() error {
 	return nil
 }
 
+// HandleContainedClient - function for checkins on server
 func HandleContainedClient() error {
 	servernets, err := models.GetNetworks()
 	if err != nil && !database.IsEmptyRecord(err) {
@@ -132,6 +138,7 @@ func HandleContainedClient() error {
 	return nil
 }
 
+// SyncNetworks - syncs the networks for servers
 func SyncNetworks(servernets []models.Network) error {
 
 	localnets, err := ncutils.GetSystemNetworks()
@@ -179,6 +186,7 @@ func SyncNetworks(servernets []models.Network) error {
 	return nil
 }
 
+// AddNetwork - add a network to server in client mode
 func AddNetwork(network string) (bool, error) {
 	err := nccommand.Join(config.ClientConfig{
 		Network: network,
@@ -188,6 +196,7 @@ func AddNetwork(network string) (bool, error) {
 			IsServer: "yes",
 			DNSOn:    "no",
 			Name:     models.NODE_SERVER_NAME,
+			MacAddress:     servercfg.GetNodeID(),
 		},
 	}, "")
 	log.Println("[netmaker] Server added to network " + network)