NET-1923: Add Metric Port to server config (#3306)

* set default metrics port 8889

* set default metrics port 51821

* add metrics port to server config

* bind caddy only on tcp

* add var for pulling files

* add new line

* update peer update model

* check if port is not zero

* set replace peer to false on pull

* do not replace peers on failover sync

* remove debug log

* add old peer update fields for backwards compatibility

* add old json tag

* add debug log in caller trace func
This commit is contained in:
Abhishek K
2025-02-04 08:44:24 +04:00
committed by GitHub
parent 04fe56db4f
commit e13bf2c0eb
14 changed files with 135 additions and 65 deletions

View File

@@ -52,8 +52,8 @@ services:
- caddy_data:/data - caddy_data:/data
- caddy_conf:/config - caddy_conf:/config
ports: ports:
- "80:80" - "80:80/tcp"
- "443:443" - "443:443/tcp"
coredns: coredns:
#network_mode: host #network_mode: host

View File

@@ -92,14 +92,15 @@ type ServerConfig struct {
JwtValidityDuration time.Duration `yaml:"jwt_validity_duration" swaggertype:"primitive,integer" format:"int64"` JwtValidityDuration time.Duration `yaml:"jwt_validity_duration" swaggertype:"primitive,integer" format:"int64"`
RacAutoDisable bool `yaml:"rac_auto_disable"` RacAutoDisable bool `yaml:"rac_auto_disable"`
CacheEnabled string `yaml:"caching_enabled"` CacheEnabled string `yaml:"caching_enabled"`
EndpointDetection bool `json:"endpoint_detection"` EndpointDetection bool `yaml:"endpoint_detection"`
AllowedEmailDomains string `yaml:"allowed_email_domains"` AllowedEmailDomains string `yaml:"allowed_email_domains"`
EmailSenderAddr string `json:"email_sender_addr"` EmailSenderAddr string `yaml:"email_sender_addr"`
EmailSenderUser string `json:"email_sender_user"` EmailSenderUser string `yaml:"email_sender_user"`
EmailSenderPassword string `json:"email_sender_password"` EmailSenderPassword string `yaml:"email_sender_password"`
SmtpHost string `json:"smtp_host"` SmtpHost string `yaml:"smtp_host"`
SmtpPort int `json:"smtp_port"` SmtpPort int `yaml:"smtp_port"`
MetricInterval string `yaml:"metric_interval"` MetricInterval string `yaml:"metric_interval"`
MetricsPort int `yaml:"metrics_port"`
ManageDNS bool `yaml:"manage_dns"` ManageDNS bool `yaml:"manage_dns"`
Stun bool `yaml:"stun"` Stun bool `yaml:"stun"`
StunServers string `yaml:"stun_servers"` StunServers string `yaml:"stun_servers"`

View File

@@ -5,7 +5,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/http" "net/http"
"os"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@@ -239,11 +238,7 @@ func pull(w http.ResponseWriter, r *http.Request) {
} }
} }
if sendPeerUpdate { if sendPeerUpdate {
reset := true if err := mq.PublishPeerUpdate(false); err != nil {
if os.Getenv("RESET_PEER_UPDATE") != "" {
reset = os.Getenv("RESET_PEER_UPDATE") == "true"
}
if err := mq.PublishPeerUpdate(reset); err != nil {
logger.Log(0, "fail to publish peer update: ", err.Error()) logger.Log(0, "fail to publish peer update: ", err.Error())
} }
} }
@@ -373,11 +368,11 @@ func hostUpdateFallback(w http.ResponseWriter, r *http.Request) {
var hostUpdate models.HostUpdate var hostUpdate models.HostUpdate
err = json.NewDecoder(r.Body).Decode(&hostUpdate) err = json.NewDecoder(r.Body).Decode(&hostUpdate)
if err != nil { if err != nil {
logger.Log(0, r.Header.Get("user"), "failed to update a host:", err.Error()) slog.Error("failed to update a host:", "user", r.Header.Get("user"), "error", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return return
} }
slog.Info("recieved host update", "name", hostUpdate.Host.Name, "id", hostUpdate.Host.ID) slog.Info("recieved host update", "name", hostUpdate.Host.Name, "id", hostUpdate.Host.ID, "action", hostUpdate.Action)
switch hostUpdate.Action { switch hostUpdate.Action {
case models.CheckIn: case models.CheckIn:
sendPeerUpdate = mq.HandleHostCheckin(&hostUpdate.Host, currentHost) sendPeerUpdate = mq.HandleHostCheckin(&hostUpdate.Host, currentHost)

View File

@@ -79,11 +79,11 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
IngressInfo: make(map[string]models.IngressInfo), IngressInfo: make(map[string]models.IngressInfo),
AclRules: make(map[string]models.AclRule), AclRules: make(map[string]models.AclRule),
}, },
PeerIDs: make(models.PeerMap, 0), PeerIDs: make(models.PeerMap, 0),
Peers: []wgtypes.PeerConfig{}, Peers: []wgtypes.PeerConfig{},
NodePeers: []wgtypes.PeerConfig{}, NodePeers: []wgtypes.PeerConfig{},
HostNetworkInfo: models.HostInfoMap{}, HostNetworkInfo: models.HostInfoMap{},
EndpointDetection: servercfg.IsEndpointDetectionEnabled(), ServerConfig: servercfg.ServerInfo,
} }
defer func() { defer func() {
if !hostPeerUpdate.FwUpdate.AllowAll { if !hostPeerUpdate.FwUpdate.AllowAll {
@@ -457,10 +457,6 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
} }
} }
} }
hostPeerUpdate.ManageDNS = servercfg.GetManageDNS()
hostPeerUpdate.Stun = servercfg.IsStunEnabled()
hostPeerUpdate.StunServers = servercfg.GetStunServers()
return hostPeerUpdate, nil return hostPeerUpdate, nil
} }

View File

@@ -7,6 +7,7 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log/slog"
"net" "net"
"os" "os"
"strings" "strings"
@@ -91,6 +92,30 @@ func StringSliceContains(slice []string, item string) bool {
} }
return false return false
} }
func SetVerbosity(logLevel int) {
var level slog.Level
switch logLevel {
case 0:
level = slog.LevelInfo
case 1:
level = slog.LevelError
case 2:
level = slog.LevelWarn
case 3:
level = slog.LevelDebug
default:
level = slog.LevelInfo
}
// Create the logger with the chosen level
handler := slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
Level: level,
})
logger := slog.New(handler)
slog.SetDefault(logger)
}
// NormalizeCIDR - returns the first address of CIDR // NormalizeCIDR - returns the first address of CIDR
func NormalizeCIDR(address string) (string, error) { func NormalizeCIDR(address string) (string, error) {

View File

@@ -48,6 +48,7 @@ type HostNetworkInfo struct {
ListenPort int `json:"listen_port" yaml:"listen_port"` ListenPort int `json:"listen_port" yaml:"listen_port"`
IsStaticPort bool `json:"is_static_port"` IsStaticPort bool `json:"is_static_port"`
IsStatic bool `json:"is_static"` IsStatic bool `json:"is_static"`
Version string `json:"version"`
} }
// PeerMap - peer map for ids and addresses in metrics // PeerMap - peer map for ids and addresses in metrics

View File

@@ -8,25 +8,29 @@ import (
// HostPeerUpdate - struct for host peer updates // HostPeerUpdate - struct for host peer updates
type HostPeerUpdate struct { type HostPeerUpdate struct {
Host Host `json:"host" bson:"host" yaml:"host"` Host Host `json:"host"`
ChangeDefaultGw bool `json:"change_default_gw"` ChangeDefaultGw bool `json:"change_default_gw"`
DefaultGwIp net.IP `json:"default_gw_ip"` DefaultGwIp net.IP `json:"default_gw_ip"`
IsInternetGw bool `json:"is_inet_gw"` IsInternetGw bool `json:"is_inet_gw"`
NodeAddrs []net.IPNet `json:"nodes_addrs" yaml:"nodes_addrs"` NodeAddrs []net.IPNet `json:"nodes_addrs"`
Server string `json:"server" bson:"server" yaml:"server"` Server string `json:"server"`
ServerVersion string `json:"serverversion" bson:"serverversion" yaml:"serverversion"` ServerVersion string `json:"serverversion"`
ServerAddrs []ServerAddr `json:"serveraddrs" bson:"serveraddrs" yaml:"serveraddrs"` ServerAddrs []ServerAddr `json:"serveraddrs"`
NodePeers []wgtypes.PeerConfig `json:"node_peers"`
Peers []wgtypes.PeerConfig `json:"host_peers"`
PeerIDs PeerMap `json:"peerids"`
HostNetworkInfo HostInfoMap `json:"host_network_info,omitempty"`
EgressRoutes []EgressNetworkRoutes `json:"egress_network_routes"`
FwUpdate FwUpdate `json:"fw_update"`
ReplacePeers bool `json:"replace_peers"`
ServerConfig
OldPeerUpdateFields
}
type OldPeerUpdateFields struct {
NodePeers []wgtypes.PeerConfig `json:"peers" bson:"peers" yaml:"peers"` NodePeers []wgtypes.PeerConfig `json:"peers" bson:"peers" yaml:"peers"`
Peers []wgtypes.PeerConfig OldPeers []wgtypes.PeerConfig `json:"Peers"`
PeerIDs PeerMap `json:"peerids" bson:"peerids" yaml:"peerids"` EndpointDetection bool `json:"endpoint_detection"`
HostNetworkInfo HostInfoMap `json:"host_network_info,omitempty" bson:"host_network_info,omitempty" yaml:"host_network_info,omitempty"`
EgressRoutes []EgressNetworkRoutes `json:"egress_network_routes"`
FwUpdate FwUpdate `json:"fw_update"`
ReplacePeers bool `json:"replace_peers"`
EndpointDetection bool `json:"endpoint_detection"`
ManageDNS bool `yaml:"manage_dns"`
Stun bool `yaml:"stun"`
StunServers string `yaml:"stun_servers"`
} }
type FwRule struct { type FwRule struct {

View File

@@ -252,24 +252,26 @@ type NodeJoinResponse struct {
// ServerConfig - struct for dealing with the server information for a netclient // ServerConfig - struct for dealing with the server information for a netclient
type ServerConfig struct { type ServerConfig struct {
CoreDNSAddr string `yaml:"corednsaddr"` CoreDNSAddr string `yaml:"corednsaddr"`
API string `yaml:"api"` API string `yaml:"api"`
APIPort string `yaml:"apiport"` APIPort string `yaml:"apiport"`
DNSMode string `yaml:"dnsmode"` DNSMode string `yaml:"dnsmode"`
Version string `yaml:"version"` Version string `yaml:"version"`
MQPort string `yaml:"mqport"` MQPort string `yaml:"mqport"`
MQUserName string `yaml:"mq_username"` MQUserName string `yaml:"mq_username"`
MQPassword string `yaml:"mq_password"` MQPassword string `yaml:"mq_password"`
BrokerType string `yaml:"broker_type"` BrokerType string `yaml:"broker_type"`
Server string `yaml:"server"` Server string `yaml:"server"`
Broker string `yaml:"broker"` Broker string `yaml:"broker"`
IsPro bool `yaml:"isee" json:"Is_EE"` IsPro bool `yaml:"isee" json:"Is_EE"`
TrafficKey []byte `yaml:"traffickey"` TrafficKey []byte `yaml:"traffickey"`
MetricInterval string `yaml:"metric_interval"` MetricInterval string `yaml:"metric_interval"`
ManageDNS bool `yaml:"manage_dns"` MetricsPort int `yaml:"metrics_port"`
Stun bool `yaml:"stun"` ManageDNS bool `yaml:"manage_dns"`
StunServers string `yaml:"stun_servers"` Stun bool `yaml:"stun"`
DefaultDomain string `yaml:"default_domain"` StunServers string `yaml:"stun_servers"`
EndpointDetection bool `yaml:"endpoint_detection"`
DefaultDomain string `yaml:"default_domain"`
} }
// User.NameInCharset - returns if name is in charset below or not // User.NameInCharset - returns if name is in charset below or not

View File

@@ -280,6 +280,7 @@ func HandleHostCheckin(h, currentHost *models.Host) bool {
(h.ListenPort != 0 && h.ListenPort != currentHost.ListenPort) || (h.ListenPort != 0 && h.ListenPort != currentHost.ListenPort) ||
(h.WgPublicListenPort != 0 && h.WgPublicListenPort != currentHost.WgPublicListenPort) || (!h.EndpointIPv6.Equal(currentHost.EndpointIPv6)) (h.WgPublicListenPort != 0 && h.WgPublicListenPort != currentHost.WgPublicListenPort) || (!h.EndpointIPv6.Equal(currentHost.EndpointIPv6))
if ifaceDelta { // only save if something changes if ifaceDelta { // only save if something changes
currentHost.EndpointIP = h.EndpointIP currentHost.EndpointIP = h.EndpointIP
currentHost.EndpointIPv6 = h.EndpointIPv6 currentHost.EndpointIPv6 = h.EndpointIPv6
currentHost.Interfaces = h.Interfaces currentHost.Interfaces = h.Interfaces

View File

@@ -17,7 +17,6 @@ import (
// PublishPeerUpdate --- determines and publishes a peer update to all the hosts // PublishPeerUpdate --- determines and publishes a peer update to all the hosts
func PublishPeerUpdate(replacePeers bool) error { func PublishPeerUpdate(replacePeers bool) error {
if !servercfg.IsMessageQueueBackend() { if !servercfg.IsMessageQueueBackend() {
return nil return nil
} }
@@ -114,6 +113,11 @@ func PublishSingleHostPeerUpdate(host *models.Host, allNodes []models.Node, dele
if err != nil { if err != nil {
return err return err
} }
peerUpdate.OldPeerUpdateFields = models.OldPeerUpdateFields{
NodePeers: peerUpdate.NodePeers,
OldPeers: peerUpdate.Peers,
EndpointDetection: peerUpdate.ServerConfig.EndpointDetection,
}
peerUpdate.ReplacePeers = replacePeers peerUpdate.ReplacePeers = replacePeers
data, err := json.Marshal(&peerUpdate) data, err := json.Marshal(&peerUpdate)
if err != nil { if err != nil {

View File

@@ -96,3 +96,7 @@ MANAGE_DNS=false
OLD_ACL_SUPPORT=true OLD_ACL_SUPPORT=true
# if STUN is set to true, hole punch is called # if STUN is set to true, hole punch is called
STUN=true STUN=true
# Metrics Collection Port
METRICS_PORT=51821
# Metrics Collection interval in minutes
PUBLISH_METRIC_INTERVAL=15

View File

@@ -6,7 +6,7 @@ SCRIPT_DIR=$(dirname "$(realpath "$0")")
CONFIG_PATH="$SCRIPT_DIR/$CONFIG_FILE" CONFIG_PATH="$SCRIPT_DIR/$CONFIG_FILE"
NM_QUICK_VERSION="0.1.1" NM_QUICK_VERSION="0.1.1"
LATEST=$(curl -s https://api.github.com/repos/gravitl/netmaker/releases/latest | grep "tag_name" | cut -d : -f 2,3 | tr -d [:space:],\") LATEST=$(curl -s https://api.github.com/repos/gravitl/netmaker/releases/latest | grep "tag_name" | cut -d : -f 2,3 | tr -d [:space:],\")
BRANCH=master
if [ $(id -u) -ne 0 ]; then if [ $(id -u) -ne 0 ]; then
echo "This script must be run as root" echo "This script must be run as root"
exit 1 exit 1
@@ -617,7 +617,7 @@ install_netmaker() {
echo "Pulling config files..." echo "Pulling config files..."
local BASE_URL="https://raw.githubusercontent.com/gravitl/netmaker/master" local BASE_URL="https://raw.githubusercontent.com/gravitl/netmaker/$BRANCH"
local COMPOSE_URL="$BASE_URL/compose/docker-compose.yml" local COMPOSE_URL="$BASE_URL/compose/docker-compose.yml"
local CADDY_URL="$BASE_URL/docker/Caddyfile" local CADDY_URL="$BASE_URL/docker/Caddyfile"
if [ "$INSTALL_TYPE" = "pro" ]; then if [ "$INSTALL_TYPE" = "pro" ]; then

View File

@@ -14,6 +14,8 @@ import (
"github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/models"
) )
var ServerInfo = GetServerInfo()
// EmqxBrokerType denotes the broker type for EMQX MQTT // EmqxBrokerType denotes the broker type for EMQX MQTT
const EmqxBrokerType = "emqx" const EmqxBrokerType = "emqx"
@@ -141,10 +143,12 @@ func GetServerInfo() models.ServerConfig {
cfg.Version = GetVersion() cfg.Version = GetVersion()
cfg.IsPro = IsPro cfg.IsPro = IsPro
cfg.MetricInterval = GetMetricInterval() cfg.MetricInterval = GetMetricInterval()
cfg.MetricsPort = GetMetricsPort()
cfg.ManageDNS = GetManageDNS() cfg.ManageDNS = GetManageDNS()
cfg.Stun = IsStunEnabled() cfg.Stun = IsStunEnabled()
cfg.StunServers = GetStunServers() cfg.StunServers = GetStunServers()
cfg.DefaultDomain = GetDefaultDomain() cfg.DefaultDomain = GetDefaultDomain()
cfg.EndpointDetection = IsEndpointDetectionEnabled()
return cfg return cfg
} }
@@ -654,6 +658,19 @@ func GetMqUserName() string {
return password return password
} }
// GetMetricsPort - get metrics port
func GetMetricsPort() int {
p := 51821
if os.Getenv("METRICS_PORT") != "" {
pStr := os.Getenv("METRICS_PORT")
pInt, err := strconv.Atoi(pStr)
if err == nil && pInt != 0 {
p = pInt
}
}
return p
}
// GetMetricInterval - get the publish metric interval // GetMetricInterval - get the publish metric interval
func GetMetricIntervalInMinutes() time.Duration { func GetMetricIntervalInMinutes() time.Duration {
//default 15 minutes //default 15 minutes

View File

@@ -1,6 +1,10 @@
package utils package utils
import "time" import (
"log/slog"
"runtime"
"time"
)
// RetryStrategy specifies a strategy to retry an operation after waiting a while, // RetryStrategy specifies a strategy to retry an operation after waiting a while,
// with hooks for successful and unsuccessful (>=max) tries. // with hooks for successful and unsuccessful (>=max) tries.
@@ -39,3 +43,19 @@ func (rs RetryStrategy) DoStrategy() {
return return
} }
} }
func TraceCaller() {
// Skip 1 frame to get the caller of this function
pc, file, line, ok := runtime.Caller(2)
if !ok {
slog.Debug("Unable to get caller information")
return
}
// Get function name from the program counter (pc)
funcName := runtime.FuncForPC(pc).Name()
// Print trace details
slog.Debug("Called from function: %s\n", "func-name", funcName)
slog.Debug("File: %s, Line: %d\n", "file", file, "line-no", line)
}