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

This commit is contained in:
Abhishek Kondur 2022-09-30 18:31:57 +05:30
parent 7783af3e58
commit 0df6d1761e
13 changed files with 125 additions and 46 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -218,3 +218,11 @@ func StringDifference(a, b []string) []string {
} }
return diff 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
}

View file

@ -135,6 +135,11 @@ func encodePasswordToPBKDF2(password string, salt string, iterations int, keyLen
// Configure - configures the dynamic initial configuration for MQ // Configure - configures the dynamic initial configuration for MQ
func Configure() error { 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 { if servercfg.Is_EE {
dynConfig.Clients = append(dynConfig.Clients, exporterMQClient) dynConfig.Clients = append(dynConfig.Clients, exporterMQClient)
dynConfig.Roles = append(dynConfig.Roles, exporterMQRole) dynConfig.Roles = append(dynConfig.Roles, exporterMQRole)
@ -165,7 +170,6 @@ func Configure() error {
if err != nil { if err != nil {
return err return err
} }
path := functions.GetNetmakerPath() + ncutils.GetSeparator() + dynamicSecurityFile
return os.WriteFile(path, data, 0755) return os.WriteFile(path, data, 0755)
} }

View file

@ -156,6 +156,18 @@ var (
Priority: -1, Priority: -1,
Allow: true, Allow: true,
}, },
{
AclType: "subscribePattern",
Topic: "#",
Priority: -1,
Allow: true,
},
{
AclType: "unsubscribePattern",
Topic: "#",
Priority: -1,
Allow: true,
},
}, },
}, },
}, },
@ -188,6 +200,18 @@ var (
Allow: true, Allow: true,
Priority: -1, 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 { func FetchNetworkAcls(network string) []Acl {
return []Acl{ return []Acl{
{ {
AclType: "publishClientReceive", AclType: "publishClientReceive",
Topic: fmt.Sprintf("update/%s/#", network), Topic: fmt.Sprintf("update/%s/#", network),
Allow: true, Priority: -1,
Allow: true,
}, },
{ {
AclType: "publishClientReceive", AclType: "publishClientReceive",
Topic: fmt.Sprintf("peers/%s/#", network), Topic: fmt.Sprintf("peers/%s/#", network),
Allow: true, 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{ return []Acl{
{ {
AclType: "publishClientSend", AclType: "publishClientSend",
Topic: fmt.Sprintf("signal/%s", nodeID), Topic: fmt.Sprintf("signal/%s", nodeID),
Allow: true, Priority: -1,
Allow: true,
}, },
{ {
AclType: "publishClientSend", AclType: "publishClientSend",
Topic: fmt.Sprintf("update/%s", nodeID), Topic: fmt.Sprintf("update/%s", nodeID),
Allow: true, Priority: -1,
Allow: true,
}, },
{ {
AclType: "publishClientSend", AclType: "publishClientSend",
Topic: fmt.Sprintf("ping/%s", nodeID), Topic: fmt.Sprintf("ping/%s", nodeID),
Allow: true, Priority: -1,
Allow: true,
}, },
{ {
AclType: "publishClientSend", AclType: "publishClientSend",
Topic: fmt.Sprintf("metrics/%s", nodeID), Topic: fmt.Sprintf("metrics/%s", nodeID),
Allow: true, Priority: -1,
Allow: true,
},
{
AclType: "subscribePattern",
Topic: "#",
Priority: -1,
Allow: true,
},
{
AclType: "unsubscribePattern",
Topic: "#",
Priority: -1,
Allow: true,
}, },
} }
} }

View file

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

View file

@ -2,6 +2,7 @@ package mq
import ( import (
"context" "context"
"fmt"
"time" "time"
mqtt "github.com/eclipse/paho.mqtt.golang" mqtt "github.com/eclipse/paho.mqtt.golang"
@ -28,9 +29,9 @@ func SetUpAdminClient() {
setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts) setMqOptions(mqAdminUserName, servercfg.GetMqAdminPassword(), opts)
mqAdminClient = mqtt.NewClient(opts) mqAdminClient = mqtt.NewClient(opts)
opts.SetOnConnectHandler(func(client mqtt.Client) { 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) 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) opts.SetOrderMatters(true)

View file

@ -233,7 +233,7 @@ func pushMetricsToExporter(metrics models.Metrics) error {
if err != nil { if err != nil {
return errors.New("failed to marshal metrics: " + err.Error()) 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 var err error
if token.Error() == nil { if token.Error() == nil {
err = errors.New("connection timeout") err = errors.New("connection timeout")

View file

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

View file

@ -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) SERVER_PUBLIC_IP=$(curl -s ifconfig.me)
MASTER_KEY=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '') MASTER_KEY=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo '')
EMAIL="$(echo $RANDOM | md5sum | head -c 32)@email.com" 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 if [ -n "$domain" ]; then
NETMAKER_BASE_DOMAIN=$domain NETMAKER_BASE_DOMAIN=$domain
fi fi
@ -128,7 +128,8 @@ sleep 5
echo "setting mosquitto.conf..." echo "setting mosquitto.conf..."
wget -q -O /root/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/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..." echo "setting docker-compose..."
mkdir -p /etc/netmaker mkdir -p /etc/netmaker