Przeglądaj źródła

Merge branch 'develop' into net-494

Gabriel de Souza Seibel 2 lat temu
rodzic
commit
dc8b3eb01a

+ 7 - 0
controllers/controller.go

@@ -14,6 +14,9 @@ import (
 	"github.com/gravitl/netmaker/servercfg"
 )
 
+// HttpMiddlewares - middleware functions for REST interactions
+var HttpMiddlewares []mux.MiddlewareFunc
+
 // HttpHandlers - handler functions for REST interactions
 var HttpHandlers = []interface{}{
 	nodeHandlers,
@@ -42,6 +45,10 @@ func HandleRESTRequests(wg *sync.WaitGroup, ctx context.Context) {
 	originsOk := handlers.AllowedOrigins(strings.Split(servercfg.GetAllowedOrigin(), ","))
 	methodsOk := handlers.AllowedMethods([]string{http.MethodGet, http.MethodPut, http.MethodPost, http.MethodDelete})
 
+	for _, middleware := range HttpMiddlewares {
+		r.Use(middleware)
+	}
+
 	for _, handler := range HttpHandlers {
 		handler.(func(*mux.Router))(r)
 	}

+ 47 - 25
controllers/node.go

@@ -16,6 +16,7 @@ import (
 	"github.com/gravitl/netmaker/mq"
 	"github.com/gravitl/netmaker/servercfg"
 	"golang.org/x/crypto/bcrypt"
+	"golang.org/x/exp/slog"
 )
 
 var hostIDHeader = "host-id"
@@ -373,11 +374,10 @@ func getNode(w http.ResponseWriter, r *http.Request) {
 
 	var params = mux.Vars(r)
 	nodeid := params["nodeid"]
-	node, err := logic.GetNodeByID(nodeid)
+
+	node, err := validateParams(nodeid, params["network"])
 	if err != nil {
-		logger.Log(0, r.Header.Get("user"),
-			fmt.Sprintf("error fetching node [ %s ] info: %v", nodeid, err))
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
 	host, err := logic.GetHost(node.HostID.String())
@@ -442,16 +442,20 @@ func getNode(w http.ResponseWriter, r *http.Request) {
 func createEgressGateway(w http.ResponseWriter, r *http.Request) {
 	var gateway models.EgressGatewayRequest
 	var params = mux.Vars(r)
-	w.Header().Set("Content-Type", "application/json")
-	err := json.NewDecoder(r.Body).Decode(&gateway)
+	node, err := validateParams(params["nodeid"], params["network"])
 	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
+		return
+	}
+	w.Header().Set("Content-Type", "application/json")
+	if err := json.NewDecoder(r.Body).Decode(&gateway); err != nil {
 		logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
 	gateway.NetID = params["network"]
 	gateway.NodeID = params["nodeid"]
-	node, err := logic.CreateEgressGateway(gateway)
+	node, err = logic.CreateEgressGateway(gateway)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"),
 			fmt.Sprintf("failed to create egress gateway on node [%s] on network [%s]: %v",
@@ -487,7 +491,12 @@ func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
 	var params = mux.Vars(r)
 	nodeid := params["nodeid"]
 	netid := params["network"]
-	node, err := logic.DeleteEgressGateway(netid, nodeid)
+	node, err := validateParams(nodeid, netid)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
+		return
+	}
+	node, err = logic.DeleteEgressGateway(netid, nodeid)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"),
 			fmt.Sprintf("failed to delete egress gateway on node [%s] on network [%s]: %v",
@@ -524,10 +533,14 @@ func createIngressGateway(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "application/json")
 	nodeid := params["nodeid"]
 	netid := params["network"]
+	node, err := validateParams(nodeid, netid)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
+		return
+	}
 	var request models.IngressRequest
 	json.NewDecoder(r.Body).Decode(&request)
-
-	node, err := logic.CreateIngressGateway(netid, nodeid, request)
+	node, err = logic.CreateIngressGateway(netid, nodeid, request)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"),
 			fmt.Sprintf("failed to create ingress gateway on node [%s] on network [%s]: %v",
@@ -566,6 +579,11 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
 	var params = mux.Vars(r)
 	nodeid := params["nodeid"]
 	netid := params["network"]
+	node, err := validateParams(nodeid, netid)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
+		return
+	}
 	node, wasFailover, removedClients, err := logic.DeleteIngressGateway(nodeid)
 	if err != nil {
 		logger.Log(0, r.Header.Get("user"),
@@ -623,14 +641,11 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 
 	//start here
 	nodeid := params["nodeid"]
-	currentNode, err := logic.GetNodeByID(nodeid)
+	currentNode, err := validateParams(nodeid, params["network"])
 	if err != nil {
-		logger.Log(0, r.Header.Get("user"),
-			fmt.Sprintf("error fetching node [ %s ] info: %v", nodeid, err))
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
 		return
 	}
-
 	var newData models.ApiNode
 	// we decode our body request params
 	err = json.NewDecoder(r.Body).Decode(&newData)
@@ -721,19 +736,13 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
 	// get params
 	var params = mux.Vars(r)
 	var nodeid = params["nodeid"]
-	forceDelete := r.URL.Query().Get("force") == "true"
-	fromNode := r.Header.Get("requestfrom") == "node"
-	node, err := logic.GetNodeByID(nodeid)
+	node, err := validateParams(nodeid, params["network"])
 	if err != nil {
-		if logic.CheckAndRemoveLegacyNode(nodeid) {
-			logger.Log(0, "removed legacy node", nodeid)
-			logic.ReturnSuccessResponse(w, r, nodeid+" deleted.")
-		} else {
-			logger.Log(0, "error retrieving node to delete", err.Error())
-			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
-		}
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
 		return
 	}
+	forceDelete := r.URL.Query().Get("force") == "true"
+	fromNode := r.Header.Get("requestfrom") == "node"
 	if r.Header.Get("ismaster") != "yes" {
 		username := r.Header.Get("user")
 		if username != "" && !doesUserOwnNode(username, params["network"], nodeid) {
@@ -816,3 +825,16 @@ func doesUserOwnNode(username, network, nodeID string) bool {
 
 	return logic.StringSliceContains(netUser.Nodes, nodeID)
 }
+
+func validateParams(nodeid, netid string) (models.Node, error) {
+	node, err := logic.GetNodeByID(nodeid)
+	if err != nil {
+		slog.Error("error fetching node", "node", nodeid, "error", err.Error())
+		return node, fmt.Errorf("error fetching node during parameter validation: %v", err)
+	}
+	if node.Network != netid {
+		slog.Error("network url param does not match node id", "url nodeid", netid, "node", node.Network)
+		return node, fmt.Errorf("network url param does not match node network")
+	}
+	return node, nil
+}

+ 11 - 12
controllers/server.go

@@ -68,22 +68,21 @@ func getUsage(w http.ResponseWriter, r *http.Request) {
 //			Responses:
 //				200: serverConfigResponse
 func getStatus(w http.ResponseWriter, r *http.Request) {
-	// TODO
-	// - check health of broker
 	type status struct {
-		DB     bool `json:"db_connected"`
-		Broker bool `json:"broker_connected"`
-		Usage  struct {
-			Hosts    int `json:"hosts"`
-			Clients  int `json:"clients"`
-			Networks int `json:"networks"`
-			Users    int `json:"users"`
-		} `json:"usage"`
+		DB           bool   `json:"db_connected"`
+		Broker       bool   `json:"broker_connected"`
+		LicenseError string `json:"license_error"`
+	}
+
+	licenseErr := ""
+	if servercfg.ErrLicenseValidation != nil {
+		licenseErr = servercfg.ErrLicenseValidation.Error()
 	}
 
 	currentServerStatus := status{
-		DB:     database.IsConnected(),
-		Broker: mq.IsConnected(),
+		DB:           database.IsConnected(),
+		Broker:       mq.IsConnected(),
+		LicenseError: licenseErr,
 	}
 
 	w.Header().Set("Content-Type", "application/json")

+ 17 - 0
ee/ee_controllers/middleware.go

@@ -0,0 +1,17 @@
+package ee_controllers
+
+import (
+	"github.com/gravitl/netmaker/logic"
+	"github.com/gravitl/netmaker/servercfg"
+	"net/http"
+)
+
+func OnlyServerAPIWhenUnlicensedMiddleware(handler http.Handler) http.Handler {
+	return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
+		if servercfg.ErrLicenseValidation != nil && request.URL.Path != "/api/server/status" {
+			logic.ReturnErrorResponse(writer, request, logic.FormatError(servercfg.ErrLicenseValidation, "forbidden"))
+			return
+		}
+		handler.ServeHTTP(writer, request)
+	})
+}

+ 11 - 4
ee/initialize.go

@@ -7,10 +7,10 @@ import (
 	controller "github.com/gravitl/netmaker/controllers"
 	"github.com/gravitl/netmaker/ee/ee_controllers"
 	eelogic "github.com/gravitl/netmaker/ee/logic"
-	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/servercfg"
+	"golang.org/x/exp/slog"
 )
 
 // InitEE - Initialize EE Logic
@@ -18,6 +18,10 @@ func InitEE() {
 	setIsEnterprise()
 	servercfg.Is_EE = true
 	models.SetLogo(retrieveEELogo())
+	controller.HttpMiddlewares = append(
+		controller.HttpMiddlewares,
+		ee_controllers.OnlyServerAPIWhenUnlicensedMiddleware,
+	)
 	controller.HttpHandlers = append(
 		controller.HttpHandlers,
 		ee_controllers.MetricHandlers,
@@ -27,8 +31,11 @@ func InitEE() {
 	)
 	logic.EnterpriseCheckFuncs = append(logic.EnterpriseCheckFuncs, func() {
 		// == License Handling ==
-		ValidateLicense()
-		logger.Log(0, "proceeding with Paid Tier license")
+		if err := ValidateLicense(); err != nil {
+			slog.Error(err.Error())
+			return
+		}
+		slog.Info("proceeding with Paid Tier license")
 		logic.SetFreeTierForTelemetry(false)
 		// == End License Handling ==
 		AddLicenseHooks()
@@ -48,7 +55,7 @@ func resetFailover() {
 		for _, net := range nets {
 			err = eelogic.ResetFailover(net.NetID)
 			if err != nil {
-				logger.Log(0, "failed to reset failover on network", net.NetID, ":", err.Error())
+				slog.Error("failed to reset failover", "network", net.NetID, "error", err.Error())
 			}
 		}
 	}

+ 33 - 21
ee/license.go

@@ -12,7 +12,6 @@ import (
 	"golang.org/x/exp/slog"
 	"io"
 	"net/http"
-	"os"
 	"time"
 
 	"github.com/gravitl/netmaker/database"
@@ -44,29 +43,40 @@ func AddLicenseHooks() {
 	}
 }
 
-// ValidateLicense - the initial license check for netmaker server
+// ValidateLicense - the initial and periodic license check for netmaker server
 // checks if a license is valid + limits are not exceeded
-// if license is free_tier and limits exceeds, then server should terminate
-// if license is not valid, server should terminate
-func ValidateLicense() error {
+// if license is free_tier and limits exceeds, then function should error
+// if license is not valid, function should error
+func ValidateLicense() (err error) {
+	defer func() {
+		if err != nil {
+			err = fmt.Errorf("%w: %s", errValidation, err.Error())
+			servercfg.ErrLicenseValidation = err
+		}
+	}()
+
 	licenseKeyValue := servercfg.GetLicenseKey()
 	netmakerTenantID := servercfg.GetNetmakerTenantID()
 	slog.Info("proceeding with Netmaker license validation...")
 	if len(licenseKeyValue) == 0 {
-		failValidation(errors.New("empty license-key (LICENSE_KEY environment variable)"))
+		err = errors.New("empty license-key (LICENSE_KEY environment variable)")
+		return err
 	}
 	if len(netmakerTenantID) == 0 {
-		failValidation(errors.New("empty tenant-id (NETMAKER_TENANT_ID environment variable)"))
+		err = errors.New("empty tenant-id (NETMAKER_TENANT_ID environment variable)")
+		return err
 	}
 
 	apiPublicKey, err := getLicensePublicKey(licenseKeyValue)
 	if err != nil {
-		failValidation(fmt.Errorf("failed to get license public key: %w", err))
+		err = fmt.Errorf("failed to get license public key: %w", err)
+		return err
 	}
 
 	tempPubKey, tempPrivKey, err := FetchApiServerKeys()
 	if err != nil {
-		failValidation(fmt.Errorf("failed to fetch api server keys: %w", err))
+		err = fmt.Errorf("failed to fetch api server keys: %w", err)
+		return err
 	}
 
 	licenseSecret := LicenseSecret{
@@ -76,35 +86,42 @@ func ValidateLicense() error {
 
 	secretData, err := json.Marshal(&licenseSecret)
 	if err != nil {
-		failValidation(fmt.Errorf("failed to marshal license secret: %w", err))
+		err = fmt.Errorf("failed to marshal license secret: %w", err)
+		return err
 	}
 
 	encryptedData, err := ncutils.BoxEncrypt(secretData, apiPublicKey, tempPrivKey)
 	if err != nil {
-		failValidation(fmt.Errorf("failed to encrypt license secret data: %w", err))
+		err = fmt.Errorf("failed to encrypt license secret data: %w", err)
+		return err
 	}
 
 	validationResponse, err := validateLicenseKey(encryptedData, tempPubKey)
 	if err != nil {
-		failValidation(fmt.Errorf("failed to validate license key: %w", err))
+		err = fmt.Errorf("failed to validate license key: %w", err)
+		return err
 	}
 	if len(validationResponse) == 0 {
-		failValidation(errors.New("empty validation response"))
+		err = errors.New("empty validation response")
+		return err
 	}
 
 	var licenseResponse ValidatedLicense
 	if err = json.Unmarshal(validationResponse, &licenseResponse); err != nil {
-		failValidation(fmt.Errorf("failed to unmarshal validation response: %w", err))
+		err = fmt.Errorf("failed to unmarshal validation response: %w", err)
+		return err
 	}
 
 	respData, err := ncutils.BoxDecrypt(base64decode(licenseResponse.EncryptedLicense), apiPublicKey, tempPrivKey)
 	if err != nil {
-		failValidation(fmt.Errorf("failed to decrypt license: %w", err))
+		err = fmt.Errorf("failed to decrypt license: %w", err)
+		return err
 	}
 
 	license := LicenseKey{}
 	if err = json.Unmarshal(respData, &license); err != nil {
-		failValidation(fmt.Errorf("failed to unmarshal license key: %w", err))
+		err = fmt.Errorf("failed to unmarshal license key: %w", err)
+		return err
 	}
 
 	slog.Info("License validation succeeded!")
@@ -158,11 +175,6 @@ func FetchApiServerKeys() (pub *[32]byte, priv *[32]byte, err error) {
 	return pub, priv, nil
 }
 
-func failValidation(err error) {
-	slog.Error(errValidation.Error(), "error", err)
-	os.Exit(0)
-}
-
 func getLicensePublicKey(licensePubKeyEncoded string) (*[32]byte, error) {
 	decodedPubKey := base64decode(licensePubKeyEncoded)
 	return ncutils.ConvertBytesToKey(decodedPubKey)

+ 0 - 1
logic/hosts.go

@@ -198,7 +198,6 @@ func UpdateHost(newHost, currentHost *models.Host) {
 	newHost.Debug = currentHost.Debug
 	newHost.Nodes = currentHost.Nodes
 	newHost.PublicKey = currentHost.PublicKey
-	newHost.InternetGateway = currentHost.InternetGateway
 	newHost.TrafficKeyPublic = currentHost.TrafficKeyPublic
 
 	// changeable fields

+ 8 - 4
logic/timer.go

@@ -3,10 +3,11 @@ package logic
 import (
 	"context"
 	"fmt"
+	"github.com/gravitl/netmaker/logger"
+	"golang.org/x/exp/slog"
 	"sync"
 	"time"
 
-	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/models"
 )
 
@@ -52,7 +53,7 @@ func StartHookManager(ctx context.Context, wg *sync.WaitGroup) {
 	for {
 		select {
 		case <-ctx.Done():
-			logger.Log(0, "## Stopping Hook Manager")
+			slog.Error("## Stopping Hook Manager")
 			return
 		case newhook := <-HookManagerCh:
 			wg.Add(1)
@@ -70,7 +71,9 @@ func addHookWithInterval(ctx context.Context, wg *sync.WaitGroup, hook func() er
 		case <-ctx.Done():
 			return
 		case <-ticker.C:
-			hook()
+			if err := hook(); err != nil {
+				slog.Error(err.Error())
+			}
 		}
 	}
 
@@ -85,6 +88,7 @@ var timeHooks = []interface{}{
 }
 
 func loggerDump() error {
+	// TODO use slog?
 	logger.DumpFile(fmt.Sprintf("data/netmaker.log.%s", time.Now().Format(logger.TimeFormatDay)))
 	return nil
 }
@@ -93,7 +97,7 @@ func loggerDump() error {
 func runHooks() {
 	for _, hook := range timeHooks {
 		if err := hook.(func() error)(); err != nil {
-			logger.Log(1, "error occurred when running timer function:", err.Error())
+			slog.Error("error occurred when running timer function", "error", err.Error())
 		}
 	}
 }

+ 0 - 6
models/api_host.go

@@ -23,7 +23,6 @@ type ApiHost struct {
 	EndpointIP         string   `json:"endpointip" yaml:"endpointip"`
 	PublicKey          string   `json:"publickey"`
 	MacAddress         string   `json:"macaddress"`
-	InternetGateway    string   `json:"internetgateway"`
 	Nodes              []string `json:"nodes"`
 	IsDefault          bool     `json:"isdefault" yaml:"isdefault"`
 	IsRelayed          bool     `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"`
@@ -45,10 +44,6 @@ func (h *Host) ConvertNMHostToAPI() *ApiHost {
 		a.Interfaces[i].AddressString = a.Interfaces[i].Address.String()
 	}
 	a.DefaultInterface = h.DefaultInterface
-	a.InternetGateway = h.InternetGateway.String()
-	if isEmptyAddr(a.InternetGateway) {
-		a.InternetGateway = ""
-	}
 	a.IsStatic = h.IsStatic
 	a.ListenPort = h.ListenPort
 	a.MTU = h.MTU
@@ -83,7 +78,6 @@ func (a *ApiHost) ConvertAPIHostToNMHost(currentHost *Host) *Host {
 	h.Interface = currentHost.Interface
 	h.Interfaces = currentHost.Interfaces
 	h.DefaultInterface = currentHost.DefaultInterface
-	h.InternetGateway = currentHost.InternetGateway
 	h.IsDocker = currentHost.IsDocker
 	h.IsK8S = currentHost.IsK8S
 	h.IsStatic = a.IsStatic

+ 0 - 1
models/host.go

@@ -55,7 +55,6 @@ type Host struct {
 	PublicKey          wgtypes.Key      `json:"publickey" yaml:"publickey"`
 	MacAddress         net.HardwareAddr `json:"macaddress" yaml:"macaddress"`
 	TrafficKeyPublic   []byte           `json:"traffickeypublic" yaml:"traffickeypublic"`
-	InternetGateway    net.UDPAddr      `json:"internetgateway" yaml:"internetgateway"`
 	Nodes              []string         `json:"nodes" yaml:"nodes"`
 	Interfaces         []Iface          `json:"interfaces" yaml:"interfaces"`
 	DefaultInterface   string           `json:"defaultinterface" yaml:"defaultinterface"`

+ 0 - 5
models/node.go

@@ -484,10 +484,6 @@ func (ln *LegacyNode) ConvertToNewNode() (*Host, *Node) {
 		host.PublicKey, _ = wgtypes.ParseKey(ln.PublicKey)
 		host.MacAddress, _ = net.ParseMAC(ln.MacAddress)
 		host.TrafficKeyPublic = ln.TrafficKeys.Mine
-		gateway, err := net.ResolveUDPAddr("udp", ln.InternetGateway)
-		if err == nil {
-			host.InternetGateway = *gateway
-		}
 		id, _ := uuid.Parse(ln.ID)
 		host.Nodes = append(host.Nodes, id.String())
 		host.Interfaces = ln.Interfaces
@@ -572,7 +568,6 @@ func (n *Node) Legacy(h *Host, s *ServerConfig, net *Network) *LegacyNode {
 	l.TrafficKeys.Mine = h.TrafficKeyPublic
 	l.TrafficKeys.Server = s.TrafficKey
 	l.FirewallInUse = h.FirewallInUse
-	l.InternetGateway = h.InternetGateway.String()
 	l.Connected = formatBool(n.Connected)
 	//l.PendingDelete = formatBool(n.PendingDelete)
 	l.DefaultACL = n.DefaultACL

+ 2 - 2
mq/publishers.go

@@ -176,7 +176,7 @@ func PublishDNSUpdate(network string, dns models.DNSUpdate) error {
 	for _, node := range nodes {
 		host, err := logic.GetHost(node.HostID.String())
 		if err != nil {
-			logger.Log(0, "error retrieving host for dns update", host.ID.String(), err.Error())
+			logger.Log(0, "error retrieving host for dns update", node.HostID.String(), err.Error())
 			continue
 		}
 		data, err := json.Marshal(dns)
@@ -370,7 +370,7 @@ func getNodeDNS(network string) []models.DNSUpdate {
 	for _, node := range nodes {
 		host, err := logic.GetHost(node.HostID.String())
 		if err != nil {
-			logger.Log(0, "error retrieving host for dns update", host.ID.String(), err.Error())
+			logger.Log(0, "error retrieving host for dns update", node.HostID.String(), err.Error())
 			continue
 		}
 		dns.Action = models.DNSInsert

+ 0 - 78
scripts/netclient-install.ps1

@@ -1,78 +0,0 @@
-new-module -name netclient-install -scriptblock {
-    $ErrorActionPreference = "Stop"
-
-    function Quit {
-        param(
-            $Text
-        )
-        Write-Host "Exiting: " $Text
-        Break Script
-    }
-    Function Netclient-Install() {
-        param ($version='latest', $token)
-
-            if($token -eq $null -or $token -eq ""){
-                Quit "-token required"
-            }
-
-            $software = "WireGuard";
-            $installed = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where { $_.DisplayName -eq $software }) -ne $null
-
-            If(-Not $installed) {
-                Write-Host "'$software' is NOT installed. installing...";
-                $url = "https://download.wireguard.com/windows-client/wireguard-installer.exe"
-                $outpath = "$env:userprofile\Downloads\wireguard-installer.exe"
-                Invoke-WebRequest -Uri $url -OutFile $outpath
-                $args = @("Comma","Separated","Arguments")
-                Start-Process -Filepath "$env:userprofile\Downloads\wireguard-installer.exe" -ArgumentList $args -Wait
-                $software = "WireGuard";
-                $installed = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where { $_.DisplayName -eq $software }) -ne $null
-                If(-Not $installed) {
-                    Quit "Could not install WireGuard"
-                } else {
-                    # $env:Path +=  (";" + $env:ProgramFiles + "\WireGuard")
-                    Write-Host "'$software' is installed."
-                }
-            } else {
-                Write-Host "'$software' is installed."
-            }
-            $outpath = "";
-            if (Test-Path -Path "C:\ProgramData\Netclient\bin\netclient.exe") {
-                $outpath = "C:\ProgramData\Netclient\bin\netclient.exe";
-            } else {
-                $outpath = "$env:userprofile\Downloads\netclient.exe"
-                Write-Host "'netclient.exe' is NOT installed. installing...";
-                Write-Host "https://github.com/gravitl/netmaker/releases/download/$version/netclient.exe";
-                $url = "https://github.com/gravitl/netmaker/releases/download/$version/netclient.exe"
-                Invoke-WebRequest -Uri $url -OutFile $outpath
-                $loc = Get-Location
-                Copy-Item -Path "$env:userprofile\Downloads\netclient.exe" -Destination "$loc\netclient.exe"
-            }
-            $runNum = "one"
-            foreach ($run in $runNum) { 
-
-                $NetArgs = @("join","-t",$token)
-                Start-Process -Filepath $outpath -ArgumentList $NetArgs -Wait
-                Add-MpPreference -ExclusionPath "C:\ProgramData\Netclient"
-
-                if ((Get-Command "netclient.exe" -ErrorAction SilentlyContinue) -eq $null) { 
-                    if (-not (Test-Path -Path "C:\ProgramData\Netclient\bin\netclient.exe")) {
-                        New-Item -Path "C:\ProgramData\Netclient" -Name "bin" -ItemType "directory"
-                        Move-Item -Path "$env:userprofile\Downloads\netclient.exe" -Destination "C:\ProgramData\Netclient\bin\netclient.exe"
-                        $oldpath = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).path
-                        $newpath = "$oldpath;C:\ProgramData\Netclient\bin"
-                        Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath
-                        $env:Path += ";C:\ProgramData\Netclient\bin"
-                    }
-                }
-                #if($run -eq "one"){
-                #    Write-Host "re-running setup to confirm all components are installed."
-                #    Start-Sleep -s 1
-                #}
-                
-            }
-        Start-Sleep -s 5
-        Write-Host "'netclient' is installed."
-    }
-}
-

+ 0 - 307
scripts/netclient-install.sh

@@ -1,307 +0,0 @@
-#!/bin/sh
-
-if [ $(id -u) -ne 0 ]; then
-   echo "This script must be run as root"
-   exit 1
-fi
-
-echo "checking dependencies..."
-
-OS=$(uname)
-
-if [ -f /etc/debian_version ]; then
-	dependencies="wireguard wireguard-tools"
-	update_cmd='apt update'
-	install_cmd='apt-get install -y'
-elif [ -f /etc/alpine-release ]; then
-	dependencies="wireguard"
-	update_cmd='apk update'
-	install_cmd='apk --update add'
-elif [ -f /etc/centos-release ]; then
-	dependencies="wireguard"
-	update_cmd='yum update'
-	install_cmd='yum install -y'
-elif [ -f /etc/fedora-release ]; then
-	dependencies="wireguard"
-	update_cmd='dnf update'
-	install_cmd='dnf install -y'
-elif [ -f /etc/redhat-release ]; then
-	dependencies="wireguard"
-	update_cmd='yum update'
-	install_cmd='yum install -y'
-elif [ -f /etc/arch-release ]; then
-    	dependecies="wireguard-tools"
-	update_cmd='pacman -Sy'
-	install_cmd='pacman -S --noconfirm'
-elif [ "${OS}" = "FreeBSD" ]; then
-	dependencies="wireguard wget"
-	update_cmd='pkg update'
-	install_cmd='pkg install -y'
-elif [ -f /etc/turris-version ]; then
-	dependencies="wireguard-tools bash"
-	OS="TurrisOS"
-	update_cmd='opkg update'	
-	install_cmd='opkg install'
-elif [ -f /etc/openwrt_release ]; then
-	dependencies="wireguard-tools bash"
-	OS="OpenWRT"
-	update_cmd='opkg update'	
-	install_cmd='opkg install'
-else
-	install_cmd=''
-fi
-
-if [ -z "${install_cmd}" ]; then
-        echo "OS unsupported for automatic dependency install"
-	exit 1
-fi
-
-${update_cmd}
-
-set -- $dependencies
-while [ -n "$1" ]; do
-    echo $1
-	if [ "${OS}" = "FreeBSD" ]; then
-		is_installed=$(pkg check -d $1 | grep "Checking" | grep "done")
-		if [ "$is_installed" != "" ]; then
-			echo "    " $1 is installed
-		else
-			echo "    " $1 is not installed. Attempting install.
-			${install_cmd} $1
-			sleep 5
-			is_installed=$(pkg check -d $1 | grep "Checking" | grep "done")
-			if [ "$is_installed" != "" ]; then
-				echo "    " $1 is installed
-			elif [ -x "$(command -v $1)" ]; then
-				echo "    " $1 is installed
-			else
-				echo "    " FAILED TO INSTALL $1
-				echo "    " This may break functionality.
-			fi
-		fi	
-	else
-		if [ "${OS}" = "OpenWRT" ] || [ "${OS}" = "TurrisOS" ]; then
-			is_installed=$(opkg list-installed $1 | grep $1)
-		else
-			is_installed=$(dpkg-query -W --showformat='${Status}\n' $1 | grep "install ok installed")
-		fi
-		if [ "${is_installed}" != "" ]; then
-			echo "    " $1 is installed
-		else
-			echo "    " $1 is not installed. Attempting install.
-			${install_cmd} $1
-			sleep 5
-			if [ "${OS}" = "OpenWRT" ] || [ "${OS}" = "TurrisOS" ]; then
-				is_installed=$(opkg list-installed $1 | grep $1)
-			else
-				is_installed=$(dpkg-query -W --showformat='${Status}\n' $1 | grep "install ok installed")
-			fi
-			if [ "${is_installed}" != "" ]; then
-				echo "    " $1 is installed
-			elif [ -x "$(command -v $1)" ]; then
-				echo "    " $1 is installed
-			else
-				echo "    " FAILED TO INSTALL $1
-				echo "    " This may break functionality.
-			fi
-		fi
-	fi
-	shift
-done
-
-set -e
-
-[ -z "$KEY" ] && KEY=nokey;
-[ -z "$VERSION" ] && echo "no \$VERSION provided, fallback to latest" && VERSION=latest;
-[ "latest" != "$VERSION" ] && [ "v" != `echo $VERSION | cut -c1` ] && VERSION="v$VERSION"
-[ -z "$NAME" ] && NAME="";
-
-dist=netclient
-
-echo "OS Version = $(uname)"
-echo "Netclient Version = $VERSION"
-
-case $(uname | tr A-Z a-z) in
-	linux*)
-		if [ -z "$CPU_ARCH" ]; then
-			CPU_ARCH=$(uname -m)
-		fi
-		case $CPU_ARCH in
-			amd64)
-				dist=netclient
-			;;
-			x86_64)
-				dist=netclient
-			;;
- 			arm64)
-				dist=netclient-arm64
-			;;
-			aarch64)
-                dist=netclient-arm64
-			;;
-			armv6l)
-                dist=netclient-arm6
-			;;
-			armv7l)
-                dist=netclient-arm7
-			;;
-			arm*)
-				dist=netclient-$CPU_ARCH
-			;;
-			mipsle)
-                dist=netclient-mipsle
-			;;
-			mips)
-			    #If binary in the below condition is not compatible with your hardware, retry with other netclient-mips* binaries.
-				if [[ `printf '\0\1' | hexdump -e '/2 "%04x"'` -eq 0100 ]]; then
-					#Little Endian, tested and confirmed in GL-MT1300 OS "OpenWrt 19.07.8"
-					dist=netclient-mipsle-softfloat
-				else
-					#Big Endian, tested and confirmed in DSL-2750U OS "OpenWrt 22.03.2"
-					dist=netclient-mips-softfloat
-				fi
-			;;
-			*)
-				fatal "$CPU_ARCH : cpu architecture not supported"
-    		esac
-	;;
-	darwin)
-        dist=netclient-darwin
-	;;
-	Darwin)
-        dist=netclient-darwin
-	;;
-	freebsd*)
-		if [ -z "$CPU_ARCH" ]; then
-			CPU_ARCH=$(uname -m)
-		fi
-		case $CPU_ARCH in
-			amd64)
-				dist=netclient-freebsd
-			;;
-			x86_64)
-				dist=netclient-freebsd
-			;;
- 			arm64)
-				dist=netclient-freebsd-arm64
-			;;
-			aarch64)
-                dist=netclient-freebsd-arm64
-			;;
-			armv7l)
-                dist=netclient-freebsd-arm7
-			;;
-			arm*)
-				dist=netclient-freebsd-$CPU_ARCH
-            ;;
-			*)
-				fatal "$CPU_ARCH : cpu architecture not supported"
-    		esac
-	;;
-esac
-
-echo "Binary = $dist"
-
-url="https://github.com/gravitl/netmaker/releases/download/$VERSION/$dist"
-curl_opts='-nv'
-if [ "${OS}" = "OpenWRT" ] || [ "${OS}" = "TurrisOS" ]; then
-	curl_opts='-q'
-fi
-
-if curl --output /dev/null --silent --head --fail "$url"; then
-	echo "Downloading $dist $VERSION"
-	wget $curl_opts -O netclient $url
-else
-	echo "Downloading $dist latest"
-	wget $curl_opts -O netclient https://github.com/gravitl/netmaker/releases/latest/download/$dist
-fi
-
-chmod +x netclient
-
-EXTRA_ARGS=""
-if [ "${OS}" = "OpenWRT" ] || [ "${OS}" = "TurrisOS" ]; then
-	EXTRA_ARGS="--daemon=off"
-fi
-
-if [ "${KEY}" != "nokey" ]; then
-  if [ -z "${NAME}" ]; then
-    ./netclient join -t $KEY $EXTRA_ARGS
-  else
-    ./netclient join -t $KEY --name $NAME $EXTRA_ARGS
-  fi
-fi
-
-if [ "${OS}" = "FreeBSD" ]; then
-  if ! [ -x /usr/sbin/netclient ]; then
-    echo "Moving netclient executable to \"/usr/sbin/netclient\""
-    mv netclient /usr/sbin  
-  else
-    echo "Netclient already present."
-  fi
-fi
-
-if [ "${OS}" = "OpenWRT" ] || [ "${OS}" = "TurrisOS" ]; then
-	mv ./netclient /sbin/netclient
-
-	if [ "${OS}" = "TurrisOS" ]; then
-		url="https://raw.githubusercontent.com/gravitl/netmaker/$VERSION/scripts/openwrt-daemon.sh"
-		if curl --output /dev/null --silent --head --fail $url; then
-			wget $curl_opts -O netclient.service.tmp $url
-		else
-			wget $curl_opts -O netclient.service.tmp https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/openwrt-daemon.sh
-		fi
-	elif [ "${OS}" = "OpenWRT" ] && [ "$CPU_ARCH" = "mips" ]; then
-		wget $curl_opts -O netclient.service.tmp https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/openwrt-daemon.sh
-	else
-		cat << 'END_OF_FILE' > ./netclient.service.tmp
-#!/bin/sh /etc/rc.common
-
-EXTRA_COMMANDS="status"
-EXTRA_HELP="        status      Check service is running"
-START=99
-
-LOG_FILE="/tmp/netclient.logs"
-
-start() {
-  if [ ! -f "${LOG_FILE}" ];then
-      touch "${LOG_FILE}"
-  fi
-  local PID=$(ps|grep "netclient daemon"|grep -v grep|awk '{print $1}')
-  if [ "${PID}" ];then
-    echo "service is running"
-    return
-  fi
-  bash -c "do /sbin/netclient daemon  >> ${LOG_FILE} 2>&1;\
-           if [ $(ls -l ${LOG_FILE}|awk '{print $5}') -gt 10240000 ];then tar zcf "${LOG_FILE}.tar" -C / "tmp/netclient.logs"  && > $LOG_FILE;fi;done &"
-  echo "start"
-}
-
-stop() {
-  pids=$(ps|grep "netclient daemon"|grep -v grep|awk '{print $1}')
-  for i in "${pids[@]}"
-  do
-	if [ "${i}" ];then
-		kill "${i}"
-	fi
-  done
-  echo "stop"
-}
-
-status() {
-  local PID=$(ps|grep "netclient daemon"|grep -v grep|awk '{print $1}')
-  if [ "${PID}" ];then
-    echo -e "netclient[${PID}] is running \n"
-  else
-    echo -e "netclient is not running \n"
-  fi
-}
-
-END_OF_FILE
-	fi
-	mv ./netclient.service.tmp /etc/init.d/netclient
-	chmod +x /etc/init.d/netclient
-	/etc/init.d/netclient enable
-	/etc/init.d/netclient start
-else 
-	rm -f netclient
-fi

+ 26 - 12
scripts/nm-certs.sh

@@ -27,20 +27,34 @@ if [ -n "$(docker ps | grep caddy)" ]; then
 	docker-compose -f /root/docker-compose.yml stop caddy
 fi
 
-CERTBOT_PARAMS=$(cat <<EOF
-certonly --standalone \
-	--non-interactive --agree-tos \
-	-m $NM_EMAIL \
-	-d api.$NM_DOMAIN \
-	-d broker.$NM_DOMAIN \
-	-d dashboard.$NM_DOMAIN \
-	-d turn.$NM_DOMAIN \
-	-d turnapi.$NM_DOMAIN \
-	-d netmaker-exporter.$NM_DOMAIN \
-	-d grafana.$NM_DOMAIN \
-	-d prometheus.$NM_DOMAIN
+if [ "$INSTALL_TYPE" = "ce" ]; then
+	CERTBOT_PARAMS=$(cat <<EOF
+	certonly --standalone \
+		--non-interactive --agree-tos \
+		-m $NM_EMAIL \
+		-d api.$NM_DOMAIN \
+		-d broker.$NM_DOMAIN \
+		-d dashboard.$NM_DOMAIN \
+		-d turn.$NM_DOMAIN \
+		-d turnapi.$NM_DOMAIN
 EOF
 )
+elif [ "$INSTALL_TYPE" = "ee" ]; then
+	CERTBOT_PARAMS=$(cat <<EOF
+	certonly --standalone \
+		--non-interactive --expand --agree-tos \
+		-m $NM_EMAIL \
+		-d api.$NM_DOMAIN \
+		-d broker.$NM_DOMAIN \
+		-d dashboard.$NM_DOMAIN \
+		-d turn.$NM_DOMAIN \
+		-d turnapi.$NM_DOMAIN \
+		-d netmaker-exporter.$NM_DOMAIN \
+		-d grafana.$NM_DOMAIN \
+		-d prometheus.$NM_DOMAIN
+EOF
+)
+fi
 
 # generate an entrypoint for zerossl-certbot
 cat <<EOF >"$SCRIPT_DIR/certbot-entry.sh"

+ 3 - 2
servercfg/serverconf.go

@@ -18,8 +18,9 @@ import (
 const EmqxBrokerType = "emqx"
 
 var (
-	Version = "dev"
-	Is_EE   = false
+	Version              = "dev"
+	Is_EE                = false
+	ErrLicenseValidation error
 )
 
 // SetHost - sets the host ip