added controller for ext client metrics and logic for ingress server

This commit is contained in:
0xdcarns
2022-10-11 14:13:17 -04:00
parent e0964fccfe
commit b7a24b98ba
4 changed files with 113 additions and 3 deletions

View File

@@ -15,6 +15,7 @@ func MetricHandlers(r *mux.Router) {
r.HandleFunc("/api/metrics/{network}/{nodeid}", logic.SecurityCheck(true, http.HandlerFunc(getNodeMetrics))).Methods("GET") r.HandleFunc("/api/metrics/{network}/{nodeid}", logic.SecurityCheck(true, http.HandlerFunc(getNodeMetrics))).Methods("GET")
r.HandleFunc("/api/metrics/{network}", logic.SecurityCheck(true, http.HandlerFunc(getNetworkNodesMetrics))).Methods("GET") r.HandleFunc("/api/metrics/{network}", logic.SecurityCheck(true, http.HandlerFunc(getNetworkNodesMetrics))).Methods("GET")
r.HandleFunc("/api/metrics", logic.SecurityCheck(true, http.HandlerFunc(getAllMetrics))).Methods("GET") r.HandleFunc("/api/metrics", logic.SecurityCheck(true, http.HandlerFunc(getAllMetrics))).Methods("GET")
r.HandleFunc("/api/metrics-ext/{network}", logic.SecurityCheck(true, http.HandlerFunc(getAllMetrics))).Methods("GET")
} }
// get the metrics of a given node // get the metrics of a given node
@@ -72,6 +73,58 @@ func getNetworkNodesMetrics(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(networkMetrics) json.NewEncoder(w).Encode(networkMetrics)
} }
// get the metrics for ext clients on a given network
func getNetworkExtMetrics(w http.ResponseWriter, r *http.Request) {
// set header.
w.Header().Set("Content-Type", "application/json")
var params = mux.Vars(r)
network := params["network"]
logger.Log(1, r.Header.Get("user"), "requested fetching external client metrics on network", network)
ingresses, err := logic.GetNetworkIngresses(network) // grab all the ingress gateways
if err != nil {
logger.Log(1, r.Header.Get("user"), "failed to fetch metrics of ext clients in network", network, err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
clients, err := logic.GetNetworkExtClients(network) // grab all the network ext clients
if err != nil {
logger.Log(1, r.Header.Get("user"), "failed to fetch metrics of ext clients in network", network, err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
networkMetrics := models.NetworkMetrics{}
networkMetrics.Nodes = make(models.MetricsMap)
for i := range ingresses {
id := ingresses[i].ID
ingressMetrics, err := logic.GetMetrics(id)
if err != nil {
logger.Log(1, r.Header.Get("user"), "failed to append external client metrics from ingress node", id, err.Error())
continue
}
if ingressMetrics.Connectivity == nil {
continue
}
for j := range clients {
if clients[j].Network != network {
continue
}
// if metrics for that client have been reported, append them
if len(ingressMetrics.Connectivity[clients[j].ClientID].NodeName) > 0 {
networkMetrics.Nodes[clients[j].ClientID] = *ingressMetrics
}
}
}
logger.Log(1, r.Header.Get("user"), "fetched ext client metrics for network", network)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(networkMetrics)
}
// get Metrics of all nodes on server, lots of data // get Metrics of all nodes on server, lots of data
func getAllMetrics(w http.ResponseWriter, r *http.Request) { func getAllMetrics(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json") w.Header().Set("Content-Type", "application/json")

View File

@@ -2,9 +2,11 @@ package logic
import ( import (
"encoding/json" "encoding/json"
"time"
"github.com/gravitl/netmaker/database" "github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/wireguard"
) )
// GetMetrics - gets the metrics // GetMetrics - gets the metrics
@@ -42,9 +44,11 @@ func DeleteMetrics(nodeid string) error {
func CollectServerMetrics(serverID string, networkNodes []models.Node) *models.Metrics { func CollectServerMetrics(serverID string, networkNodes []models.Node) *models.Metrics {
newServerMetrics := models.Metrics{} newServerMetrics := models.Metrics{}
newServerMetrics.Connectivity = make(map[string]models.Metric) newServerMetrics.Connectivity = make(map[string]models.Metric)
var serverNode models.Node
for i := range networkNodes { for i := range networkNodes {
currNodeID := networkNodes[i].ID currNodeID := networkNodes[i].ID
if currNodeID == serverID { if currNodeID == serverID {
serverNode = networkNodes[i]
continue continue
} }
if currMetrics, err := GetMetrics(currNodeID); err == nil { if currMetrics, err := GetMetrics(currNodeID); err == nil {
@@ -61,5 +65,43 @@ func CollectServerMetrics(serverID string, networkNodes []models.Node) *models.M
} }
} }
} }
if serverNode.IsIngressGateway == "yes" {
clients, err := GetExtClientsByID(serverID, serverNode.Network)
if err == nil {
peers, err := wireguard.GetDevicePeers(serverNode.Interface)
if err == nil {
for i := range clients {
for j := range peers {
if clients[i].PublicKey == peers[j].PublicKey.String() {
if peers[j].LastHandshakeTime.Before(time.Now().Add(-(time.Minute * 3))) &&
peers[j].ReceiveBytes > 0 &&
peers[j].TransmitBytes > 0 {
newServerMetrics.Connectivity[clients[i].ClientID] = models.Metric{
NodeName: clients[i].ClientID,
TotalTime: 1,
Uptime: 1,
IsServer: "no",
TotalReceived: peers[j].ReceiveBytes,
TotalSent: peers[j].TransmitBytes,
Connected: true,
}
} else {
newServerMetrics.Connectivity[clients[i].ClientID] = models.Metric{
NodeName: clients[i].ClientID,
TotalTime: 1,
Uptime: 0,
IsServer: "no",
Connected: false,
Latency: 999,
}
}
}
}
}
}
}
}
return &newServerMetrics return &newServerMetrics
} }

View File

@@ -741,6 +741,21 @@ func findNode(ip string) (*models.Node, error) {
return nil, errors.New("node not found") return nil, errors.New("node not found")
} }
// GetNetworkIngresses - gets the gateways of a network
func GetNetworkIngresses(network string) ([]models.Node, error) {
var ingresses []models.Node
netNodes, err := GetNetworkNodes(network)
if err != nil {
return []models.Node{}, err
}
for i := range netNodes {
if netNodes[i].IsIngressGateway == "yes" {
ingresses = append(ingresses, netNodes[i])
}
}
return ingresses, nil
}
// == PRO == // == PRO ==
func updateProNodeACLS(node *models.Node) error { func updateProNodeACLS(node *models.Node) error {

View File

@@ -238,10 +238,10 @@ func updateNodeMetrics(currentNode *models.Node, newMetrics *models.Metrics) boo
// associate ext clients with IDs // associate ext clients with IDs
for i := range attachedClients { for i := range attachedClients {
extMetric := newMetrics.Connectivity[attachedClients[i].PublicKey] extMetric := newMetrics.Connectivity[attachedClients[i].PublicKey]
extMetric.NodeName = attachedClients[i].ClientID
extMetric.IsServer = "no"
delete(newMetrics.Connectivity, attachedClients[i].PublicKey) delete(newMetrics.Connectivity, attachedClients[i].PublicKey)
if extMetric.Connected { // add ext client metrics newMetrics.Connectivity[attachedClients[i].ClientID] = extMetric
newMetrics.Connectivity[attachedClients[i].ClientID] = extMetric
}
} }
} }