From 0df6d1761e9e3451d06a8c912ce0dfa569d44c09 Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Fri, 30 Sep 2022 18:31:57 +0530 Subject: [PATCH] add subscription pattern to acls,fix NaN value in metrics for uptime,get real iface name for mac --- compose/docker-compose.ee.yml | 7 ++- compose/docker-compose.yml | 2 +- controllers/node.go | 19 ++++---- logic/metrics.go | 1 + logic/metrics/metrics.go | 10 ++++ logic/util.go | 8 ++++ mq/dynsec.go | 6 ++- mq/dynsec_helper.go | 90 ++++++++++++++++++++++++++++------- mq/handlers.go | 6 ++- mq/mq.go | 5 +- mq/publishers.go | 2 +- netclient/wireguard/mac.go | 10 ++-- scripts/nm-quick.sh | 5 +- 13 files changed, 125 insertions(+), 46 deletions(-) diff --git a/compose/docker-compose.ee.yml b/compose/docker-compose.ee.yml index 9253968c..844fda74 100644 --- a/compose/docker-compose.ee.yml +++ b/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: {} diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 57a28d92..449550d4 100644 --- a/compose/docker-compose.yml +++ b/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 diff --git a/controllers/node.go b/controllers/node.go index e221396e..a1e0c9bd 100644 --- a/controllers/node.go +++ b/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), diff --git a/logic/metrics.go b/logic/metrics.go index f60bcd76..f7fd44f5 100644 --- a/logic/metrics.go +++ b/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, } } } diff --git a/logic/metrics/metrics.go b/logic/metrics/metrics.go index efa3b58b..fd9fbbc7 100644 --- a/logic/metrics/metrics.go +++ b/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) diff --git a/logic/util.go b/logic/util.go index 6fe25af8..a87faca9 100644 --- a/logic/util.go +++ b/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 +} diff --git a/mq/dynsec.go b/mq/dynsec.go index 9ce66b49..e19eb0fe 100644 --- a/mq/dynsec.go +++ b/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) } diff --git a/mq/dynsec_helper.go b/mq/dynsec_helper.go index 3df1eb05..2753b30f 100644 --- a/mq/dynsec_helper.go +++ b/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), - Allow: true, + AclType: "publishClientReceive", + Topic: fmt.Sprintf("peers/%s/#", network), + Priority: -1, + Allow: true, + }, + { + AclType: "subscribePattern", + Topic: "#", + Priority: -1, + 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), - Allow: true, + AclType: "publishClientSend", + Topic: fmt.Sprintf("update/%s", nodeID), + Priority: -1, + Allow: true, }, { - AclType: "publishClientSend", - Topic: fmt.Sprintf("ping/%s", nodeID), - Allow: true, + AclType: "publishClientSend", + Topic: fmt.Sprintf("ping/%s", nodeID), + Priority: -1, + Allow: true, }, { - AclType: "publishClientSend", - Topic: fmt.Sprintf("metrics/%s", nodeID), - Allow: true, + AclType: "publishClientSend", + Topic: fmt.Sprintf("metrics/%s", nodeID), + Priority: -1, + Allow: true, + }, + { + AclType: "subscribePattern", + Topic: "#", + Priority: -1, + Allow: true, + }, + { + AclType: "unsubscribePattern", + Topic: "#", + Priority: -1, + Allow: true, }, } } diff --git a/mq/handlers.go b/mq/handlers.go index 517010ca..db4ec42a 100644 --- a/mq/handlers.go +++ b/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 diff --git a/mq/mq.go b/mq/mq.go index 64db9307..67888555 100644 --- a/mq/mq.go +++ b/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) diff --git a/mq/publishers.go b/mq/publishers.go index 8b2f3205..3d002812 100644 --- a/mq/publishers.go +++ b/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") diff --git a/netclient/wireguard/mac.go b/netclient/wireguard/mac.go index 4c9f08ba..f3569781 100644 --- a/netclient/wireguard/mac.go +++ b/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 } diff --git a/scripts/nm-quick.sh b/scripts/nm-quick.sh index e241108c..d08afe2d 100755 --- a/scripts/nm-quick.sh +++ b/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