Browse Source

Merge pull request #3718 from gravitl/fix/v1.2.0

Fixes v1.2.0
Vishal Dalwadi 1 month ago
parent
commit
fc20b38851

+ 11 - 0
controllers/node.go

@@ -704,6 +704,17 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 		if servercfg.IsDNSMode() {
 			logic.SetDNS()
 		}
+		if !newNode.Connected {
+			metrics, err := logic.GetMetrics(newNode.ID.String())
+			if err == nil {
+				for peer, connectivity := range metrics.Connectivity {
+					connectivity.Connected = false
+					metrics.Connectivity[peer] = connectivity
+				}
+
+				_ = logic.UpdateMetrics(newNode.ID.String(), metrics)
+			}
+		}
 	}(aclUpdate, relayUpdate, newNode)
 }
 

+ 4 - 0
controllers/server.go

@@ -282,6 +282,10 @@ func reInit(curr, new models.ServerSettings, force bool) {
 	logic.EmailInit()
 	logic.SetVerbosity(int(logic.GetServerSettings().Verbosity))
 	logic.ResetIDPSyncHook()
+	if curr.MetricInterval != new.MetricInterval {
+		logic.GetMetricsMonitor().Stop()
+		logic.GetMetricsMonitor().Start()
+	}
 	// check if auto update is changed
 	if force {
 		if curr.NetclientAutoUpdate != new.NetclientAutoUpdate {

+ 64 - 0
logic/metrics.go

@@ -1,9 +1,73 @@
 package logic
 
 import (
+	"context"
+	"math"
+	"strconv"
+	"time"
+
 	"github.com/gravitl/netmaker/models"
 )
 
+type MetricsMonitor struct {
+	cancel context.CancelFunc
+}
+
+var metricsMonitor MetricsMonitor
+
+func GetMetricsMonitor() *MetricsMonitor {
+	return &metricsMonitor
+}
+
+func (m *MetricsMonitor) Start() {
+	if m.cancel != nil {
+		m.cancel()
+		m.cancel = nil
+	}
+
+	var ctx context.Context
+	ctx, m.cancel = context.WithCancel(context.Background())
+
+	go func(ctx context.Context) {
+		metricsInterval, _ := strconv.Atoi(GetServerSettings().MetricInterval)
+		if metricsInterval == 0 {
+			return
+		}
+
+		checkInterval := time.Duration(2*metricsInterval) * time.Minute
+		for {
+			select {
+			case <-time.After(checkInterval):
+				nodes, _ := GetAllNodes()
+				for _, node := range nodes {
+					if node.Connected || node.PendingDelete {
+						continue
+					}
+
+					nodeMetrics, err := GetMetrics(node.ID.String())
+					if err == nil {
+						inc := math.Round(float64(time.Since(nodeMetrics.UpdatedAt)) / float64(time.Minute))
+						for peer, peerMetrics := range nodeMetrics.Connectivity {
+							peerMetrics.TotalTime += int64(inc)
+							peerMetrics.PercentUp = 100.0 * (float64(peerMetrics.Uptime) / float64(peerMetrics.TotalTime))
+							nodeMetrics.Connectivity[peer] = peerMetrics
+						}
+
+						_ = UpdateMetrics(node.ID.String(), nodeMetrics)
+					}
+				}
+			case <-ctx.Done():
+				return
+			}
+		}
+	}(ctx)
+}
+
+func (m *MetricsMonitor) Stop() {
+	m.cancel()
+	m.cancel = nil
+}
+
 var DeleteMetrics = func(string) error {
 	return nil
 }

+ 1 - 0
models/metrics.go

@@ -10,6 +10,7 @@ type Metrics struct {
 	NodeID       string            `json:"node_id" bson:"node_id" yaml:"node_id"`
 	NodeName     string            `json:"node_name" bson:"node_name" yaml:"node_name"`
 	Connectivity map[string]Metric `json:"connectivity" bson:"connectivity" yaml:"connectivity"`
+	UpdatedAt    time.Time         `json:"updated_at" bson:"updated_at" yaml:"updated_at"`
 }
 
 // Metric - holds a metric for data between nodes

+ 1 - 1
pro/auth/headless_callback.go

@@ -98,7 +98,7 @@ func HandleHeadlessSSOCallback(w http.ResponseWriter, r *http.Request) {
 	var response bytes.Buffer
 	if err := ssoCallbackTemplate.Execute(&response, ssoCallbackTemplateConfig{
 		User: userClaims.getUserName(),
-		Verb: "Authenticated",
+		Verb: "authenticated",
 	}); err != nil {
 		logger.Log(0, "Could not render SSO callback template ", err.Error())
 		response := returnErrTemplate(userClaims.getUserName(), "Could not render SSO callback template", state, reqKeyIf)

+ 1 - 1
pro/auth/register_callback.go

@@ -86,7 +86,7 @@ func HandleHostSSOCallback(w http.ResponseWriter, r *http.Request) {
 	var response bytes.Buffer
 	if err := ssoCallbackTemplate.Execute(&response, ssoCallbackTemplateConfig{
 		User: userClaims.getUserName(),
-		Verb: "Authenticated",
+		Verb: "authenticated",
 	}); err != nil {
 		logger.Log(0, "Could not render SSO callback template ", err.Error())
 		response := returnErrTemplate(reqKeyIf.User, "Could not render SSO callback template", state, reqKeyIf)

+ 1 - 1
pro/email/invite.go

@@ -53,7 +53,7 @@ func (invite UserInvitedMail) GetBody(info Notification) string {
 		WithHtml("</ol>").
 		WithParagraph("Important Information:").
 		WithHtml("<ul>").
-		WithHtml(fmt.Sprintf("<li>When connecting through RAC, please enter your server connection ID: %s.</li>", connectionID)).
+		WithHtml(fmt.Sprintf("<li>When connecting through Netmaker Desktop, please enter your server connection ID: %s.</li>", connectionID)).
 		WithHtml("</ul>").
 		WithParagraph(fmt.Sprintf("If you have any questions or need assistance, please contact our support team at <a href=\"mailto:%s\">%s</a>.", supportEmail, supportEmail)).
 		WithParagraph("Best Regards,").

+ 2 - 0
pro/initialize.go

@@ -99,6 +99,8 @@ func InitPro() {
 		auth.ResetIDPSyncHook()
 		email.Init()
 		go proLogic.EventWatcher()
+
+		logic.GetMetricsMonitor().Start()
 	})
 	logic.ResetFailOver = proLogic.ResetFailOver
 	logic.ResetFailedOverPeer = proLogic.ResetFailedOverPeer

+ 1 - 0
pro/logic/metrics.go

@@ -93,6 +93,7 @@ func GetMetrics(nodeid string) (*models.Metrics, error) {
 
 // UpdateMetrics - updates the metrics of a given client
 func UpdateMetrics(nodeid string, metrics *models.Metrics) error {
+	metrics.UpdatedAt = time.Now()
 	data, err := json.Marshal(metrics)
 	if err != nil {
 		return err