Browse Source

add subscription pattern to acls,fix NaN value in metrics for uptime,get real iface name for mac

Abhishek Kondur 2 years ago
parent
commit
0df6d1761e

+ 3 - 4
compose/docker-compose.ee.yml

@@ -17,7 +17,7 @@ services:
     volumes:
       - dnsconfig:/root/config/dnsconfig
       - sqldata:/root/data
-      - shared_certs:/etc/netmaker
+      - mosquitto_data:/etc/netmaker
     environment:
       SERVER_NAME: "broker.NETMAKER_BASE_DOMAIN"
       SERVER_HOST: "SERVER_PUBLIC_IP"
@@ -115,7 +115,7 @@ services:
     restart: unless-stopped
     command: ["/mosquitto/config/wait.sh"]
     environment:
-      NETMAKER_SERVER_HOST: "api.NETMAKER_BASE_DOMAIN"
+      NETMAKER_SERVER_HOST: "https://api.NETMAKER_BASE_DOMAIN"
     volumes:
       - /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
       - /root/wait.sh:/mosquitto/config/wait.sh
@@ -182,7 +182,7 @@ services:
     environment:
       MQ_HOST: "mq"
       MQ_PORT: "443"
-      MQ_SERVER_PORT: "1884"
+      MQ_SERVER_PORT: "1883"
       PROMETHEUS: "on"
       VERBOSITY: "1"
       API_PORT: "8085"
@@ -192,7 +192,6 @@ services:
       - "8085"
 volumes:
   traefik_certs: {}
-  shared_certs: {}
   sqldata: {}
   dnsconfig: {}
   mosquitto_data: {}

+ 1 - 1
compose/docker-compose.yml

@@ -112,7 +112,7 @@ services:
     restart: unless-stopped
     command: ["/mosquitto/config/wait.sh"]
     environment:
-     NETMAKER_SERVER_HOST: "api.NETMAKER_BASE_DOMAIN"
+     NETMAKER_SERVER_HOST: "https://api.NETMAKER_BASE_DOMAIN"
     volumes:
       - /root/mosquitto.conf:/mosquitto/config/mosquitto.conf
       - /root/wait.sh:/mosquitto/config/wait.sh

+ 8 - 11
controllers/node.go

@@ -661,23 +661,20 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 		return
 	}
-	// Delete Any Existing Client with this ID.
+
+	// Create client for this node in Mq
 	event := mq.MqDynsecPayload{
 		Commands: []mq.MqDynSecCmd{
 			{
 				Command:  mq.DeleteClientCmd,
 				Username: node.ID,
 			},
-		},
-	}
-
-	if err := mq.PublishEventToDynSecTopic(event); err != nil {
-		logger.Log(0, fmt.Sprintf("failed to send DynSec command [%v]: %v",
-			event.Commands, err.Error()))
-	}
-	// Create client for this node in Mq
-	event = mq.MqDynsecPayload{
-		Commands: []mq.MqDynSecCmd{
+			{
+				Command:  mq.CreateRoleCmd,
+				RoleName: node.Network,
+				Textname: "Network wide role with Acls for nodes",
+				Acls:     mq.FetchNetworkAcls(node.Network),
+			},
 			{
 				Command:  mq.CreateRoleCmd,
 				RoleName: fmt.Sprintf("%s-%s", "Node", node.ID),

+ 1 - 0
logic/metrics.go

@@ -58,6 +58,7 @@ func CollectServerMetrics(serverID string, networkNodes []models.Node) *models.M
 			newServerMetrics.Connectivity[currNodeID] = models.Metric{
 				Connected: false,
 				Latency:   999,
+				PercentUp: 0,
 			}
 		}
 	}

+ 10 - 0
logic/metrics/metrics.go

@@ -1,12 +1,14 @@
 package metrics
 
 import (
+	"runtime"
 	"time"
 
 	"github.com/go-ping/ping"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
+	"github.com/gravitl/netmaker/netclient/wireguard"
 	"golang.zx2c4.com/wireguard/wgctrl"
 )
 
@@ -20,6 +22,14 @@ func Collect(iface string, peerMap models.PeerMap) (*models.Metrics, error) {
 		return &metrics, err
 	}
 	defer wgclient.Close()
+
+	if runtime.GOOS == "darwin" {
+		iface, err = wireguard.GetRealIface(iface)
+		if err != nil {
+			fillUnconnectedData(&metrics, peerMap)
+			return &metrics, err
+		}
+	}
 	device, err := wgclient.Device(iface)
 	if err != nil {
 		fillUnconnectedData(&metrics, peerMap)

+ 8 - 0
logic/util.go

@@ -218,3 +218,11 @@ func StringDifference(a, b []string) []string {
 	}
 	return diff
 }
+
+// CheckIfFileExists - checks if file exists or no in the given path
+func CheckIfFileExists(filePath string) bool {
+	if _, err := os.Stat(filePath); os.IsNotExist(err) {
+		return false
+	}
+	return true
+}

+ 5 - 1
mq/dynsec.go

@@ -135,6 +135,11 @@ func encodePasswordToPBKDF2(password string, salt string, iterations int, keyLen
 
 // Configure - configures the dynamic initial configuration for MQ
 func Configure() error {
+	path := functions.GetNetmakerPath() + ncutils.GetSeparator() + dynamicSecurityFile
+	if logic.CheckIfFileExists(path) {
+		logger.Log(0, "MQ Is Already Configured, Skipping...")
+		return nil
+	}
 	if servercfg.Is_EE {
 		dynConfig.Clients = append(dynConfig.Clients, exporterMQClient)
 		dynConfig.Roles = append(dynConfig.Roles, exporterMQRole)
@@ -165,7 +170,6 @@ func Configure() error {
 	if err != nil {
 		return err
 	}
-	path := functions.GetNetmakerPath() + ncutils.GetSeparator() + dynamicSecurityFile
 	return os.WriteFile(path, data, 0755)
 }
 

+ 72 - 18
mq/dynsec_helper.go

@@ -156,6 +156,18 @@ var (
 						Priority: -1,
 						Allow:    true,
 					},
+					{
+						AclType:  "subscribePattern",
+						Topic:    "#",
+						Priority: -1,
+						Allow:    true,
+					},
+					{
+						AclType:  "unsubscribePattern",
+						Topic:    "#",
+						Priority: -1,
+						Allow:    true,
+					},
 				},
 			},
 		},
@@ -188,6 +200,18 @@ var (
 				Allow:    true,
 				Priority: -1,
 			},
+			{
+				AclType:  "subscribePattern",
+				Topic:    "#",
+				Priority: -1,
+				Allow:    true,
+			},
+			{
+				AclType:  "unsubscribePattern",
+				Topic:    "#",
+				Priority: -1,
+				Allow:    true,
+			},
 		},
 	}
 )
@@ -268,14 +292,28 @@ func ListClients(client mqtt.Client) (ListClientsData, error) {
 func FetchNetworkAcls(network string) []Acl {
 	return []Acl{
 		{
-			AclType: "publishClientReceive",
-			Topic:   fmt.Sprintf("update/%s/#", network),
-			Allow:   true,
+			AclType:  "publishClientReceive",
+			Topic:    fmt.Sprintf("update/%s/#", network),
+			Priority: -1,
+			Allow:    true,
+		},
+		{
+			AclType:  "publishClientReceive",
+			Topic:    fmt.Sprintf("peers/%s/#", network),
+			Priority: -1,
+			Allow:    true,
+		},
+		{
+			AclType:  "subscribePattern",
+			Topic:    "#",
+			Priority: -1,
+			Allow:    true,
 		},
 		{
-			AclType: "publishClientReceive",
-			Topic:   fmt.Sprintf("peers/%s/#", network),
-			Allow:   true,
+			AclType:  "unsubscribePattern",
+			Topic:    "#",
+			Priority: -1,
+			Allow:    true,
 		},
 	}
 }
@@ -285,24 +323,40 @@ func FetchNodeAcls(nodeID string) []Acl {
 	return []Acl{
 
 		{
-			AclType: "publishClientSend",
-			Topic:   fmt.Sprintf("signal/%s", nodeID),
-			Allow:   true,
+			AclType:  "publishClientSend",
+			Topic:    fmt.Sprintf("signal/%s", nodeID),
+			Priority: -1,
+			Allow:    true,
+		},
+		{
+			AclType:  "publishClientSend",
+			Topic:    fmt.Sprintf("update/%s", nodeID),
+			Priority: -1,
+			Allow:    true,
+		},
+		{
+			AclType:  "publishClientSend",
+			Topic:    fmt.Sprintf("ping/%s", nodeID),
+			Priority: -1,
+			Allow:    true,
 		},
 		{
-			AclType: "publishClientSend",
-			Topic:   fmt.Sprintf("update/%s", nodeID),
-			Allow:   true,
+			AclType:  "publishClientSend",
+			Topic:    fmt.Sprintf("metrics/%s", nodeID),
+			Priority: -1,
+			Allow:    true,
 		},
 		{
-			AclType: "publishClientSend",
-			Topic:   fmt.Sprintf("ping/%s", nodeID),
-			Allow:   true,
+			AclType:  "subscribePattern",
+			Topic:    "#",
+			Priority: -1,
+			Allow:    true,
 		},
 		{
-			AclType: "publishClientSend",
-			Topic:   fmt.Sprintf("metrics/%s", nodeID),
-			Allow:   true,
+			AclType:  "unsubscribePattern",
+			Topic:    "#",
+			Priority: -1,
+			Allow:    true,
 		},
 	}
 }

+ 5 - 1
mq/handlers.go

@@ -225,7 +225,11 @@ func updateNodeMetrics(currentNode *models.Node, newMetrics *models.Metrics) {
 		oldMetric := oldMetrics.Connectivity[k]
 		currMetric.TotalTime += oldMetric.TotalTime
 		currMetric.Uptime += oldMetric.Uptime // get the total uptime for this connection
-		currMetric.PercentUp = 100.0 * (float64(currMetric.Uptime) / float64(currMetric.TotalTime))
+		if currMetric.Uptime == 0 || currMetric.TotalTime == 0 {
+			currMetric.PercentUp = 0
+		} else {
+			currMetric.PercentUp = 100.0 * (float64(currMetric.Uptime) / float64(currMetric.TotalTime))
+		}
 		totalUpMinutes := currMetric.Uptime * 5
 		currMetric.ActualUptime = time.Duration(totalUpMinutes) * time.Minute
 		delete(oldMetrics.Connectivity, k) // remove from old data

+ 3 - 2
mq/mq.go

@@ -2,6 +2,7 @@ package mq
 
 import (
 	"context"
+	"fmt"
 	"time"
 
 	mqtt "github.com/eclipse/paho.mqtt.golang"
@@ -28,9 +29,9 @@ func SetUpAdminClient() {
 	setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
 	mqAdminClient = mqtt.NewClient(opts)
 	opts.SetOnConnectHandler(func(client mqtt.Client) {
-		if token := client.Subscribe(dynamicSecSubTopic, 0, mqtt.MessageHandler(watchDynSecTopic)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil {
+		if token := client.Subscribe(dynamicSecSubTopic, 2, mqtt.MessageHandler(watchDynSecTopic)); token.WaitTimeout(MQ_TIMEOUT*time.Second) && token.Error() != nil {
 			client.Disconnect(240)
-			logger.Log(0, "Dynamic security client subscription failed")
+			logger.Log(0, fmt.Sprintf("Dynamic security client subscription failed: %v ", token.Error()))
 		}
 
 		opts.SetOrderMatters(true)

+ 1 - 1
mq/publishers.go

@@ -233,7 +233,7 @@ func pushMetricsToExporter(metrics models.Metrics) error {
 	if err != nil {
 		return errors.New("failed to marshal metrics: " + err.Error())
 	}
-	if token := mqclient.Publish("metrics_exporter", 0, true, data); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
+	if token := mqclient.Publish("metrics_exporter", 2, true, data); !token.WaitTimeout(MQ_TIMEOUT*time.Second) || token.Error() != nil {
 		var err error
 		if token.Error() == nil {
 			err = errors.New("connection timeout")

+ 5 - 5
netclient/wireguard/mac.go

@@ -26,7 +26,7 @@ func WgQuickDownMac(node *models.Node, iface string) error {
 
 // RemoveConfMac - bring down mac interface and remove routes
 func RemoveConfMac(iface string) error {
-	realIface, err := getRealIface(iface)
+	realIface, err := GetRealIface(iface)
 	if realIface != "" {
 		err = deleteInterface(iface, realIface)
 	}
@@ -37,7 +37,7 @@ func RemoveConfMac(iface string) error {
 func WgQuickUpMac(node *models.Node, iface string, confPath string) error {
 	var err error
 	var realIface string
-	realIface, err = getRealIface(iface)
+	realIface, err = GetRealIface(iface)
 	if realIface != "" && err == nil {
 		deleteInterface(iface, realIface)
 		deleteRoutes(realIface)
@@ -101,8 +101,8 @@ func addInterface(iface string) (string, error) {
 	return realIface, err
 }
 
-// getRealIface - retrieves tun iface based on reference iface name from config file
-func getRealIface(iface string) (string, error) {
+// GetRealIface - retrieves tun iface based on reference iface name from config file
+func GetRealIface(iface string) (string, error) {
 	ncutils.RunCmd("wg show interfaces", false)
 	ifacePath := "/var/run/wireguard/" + iface + ".name"
 	if !(ncutils.FileExists(ifacePath)) {
@@ -120,7 +120,7 @@ func getRealIface(iface string) (string, error) {
 
 // deleteRoutes - deletes network routes associated with interface
 func deleteRoutes(iface string) error {
-	realIface, err := getRealIface(iface)
+	realIface, err := GetRealIface(iface)
 	if err != nil {
 		return err
 	}

+ 3 - 2
scripts/nm-quick.sh

@@ -80,7 +80,7 @@ COREDNS_IP=$(ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p')
 SERVER_PUBLIC_IP=$(curl -s ifconfig.me)
 MASTER_KEY=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
 EMAIL="$(echo $RANDOM | md5sum  | head -c 32)@email.com"
-MQ_ADMIN_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
+MQ_ADMIN_PASSWORD=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 64 ; echo '')
 if [ -n "$domain" ]; then
   NETMAKER_BASE_DOMAIN=$domain
 fi
@@ -128,7 +128,8 @@ sleep 5
 echo "setting mosquitto.conf..."
 
 wget -q -O /root/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/mosquitto.conf
-
+wget -q -O /root/wait.sh https://raw.githubusercontent.com/gravitl/netmaker/master/docker/wait.sh
+chmod +x /root/wait.sh
 echo "setting docker-compose..."
 
 mkdir -p /etc/netmaker