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
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 135 additions and 65 deletions

View file

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

View file

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

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"os"
"github.com/google/uuid"
"github.com/gorilla/mux"
@ -239,11 +238,7 @@ func pull(w http.ResponseWriter, r *http.Request) {
}
}
if sendPeerUpdate {
reset := true
if os.Getenv("RESET_PEER_UPDATE") != "" {
reset = os.Getenv("RESET_PEER_UPDATE") == "true"
}
if err := mq.PublishPeerUpdate(reset); err != nil {
if err := mq.PublishPeerUpdate(false); err != nil {
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
err = json.NewDecoder(r.Body).Decode(&hostUpdate)
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"))
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 {
case models.CheckIn:
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),
AclRules: make(map[string]models.AclRule),
},
PeerIDs: make(models.PeerMap, 0),
Peers: []wgtypes.PeerConfig{},
NodePeers: []wgtypes.PeerConfig{},
HostNetworkInfo: models.HostInfoMap{},
EndpointDetection: servercfg.IsEndpointDetectionEnabled(),
PeerIDs: make(models.PeerMap, 0),
Peers: []wgtypes.PeerConfig{},
NodePeers: []wgtypes.PeerConfig{},
HostNetworkInfo: models.HostInfoMap{},
ServerConfig: servercfg.ServerInfo,
}
defer func() {
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
}

View file

@ -7,6 +7,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"log/slog"
"net"
"os"
"strings"
@ -91,6 +92,30 @@ func StringSliceContains(slice []string, item string) bool {
}
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
func NormalizeCIDR(address string) (string, error) {

View file

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

View file

@ -8,25 +8,29 @@ import (
// HostPeerUpdate - struct for host peer updates
type HostPeerUpdate struct {
Host Host `json:"host" bson:"host" yaml:"host"`
ChangeDefaultGw bool `json:"change_default_gw"`
DefaultGwIp net.IP `json:"default_gw_ip"`
IsInternetGw bool `json:"is_inet_gw"`
NodeAddrs []net.IPNet `json:"nodes_addrs" yaml:"nodes_addrs"`
Server string `json:"server" bson:"server" yaml:"server"`
ServerVersion string `json:"serverversion" bson:"serverversion" yaml:"serverversion"`
ServerAddrs []ServerAddr `json:"serveraddrs" bson:"serveraddrs" yaml:"serveraddrs"`
Host Host `json:"host"`
ChangeDefaultGw bool `json:"change_default_gw"`
DefaultGwIp net.IP `json:"default_gw_ip"`
IsInternetGw bool `json:"is_inet_gw"`
NodeAddrs []net.IPNet `json:"nodes_addrs"`
Server string `json:"server"`
ServerVersion string `json:"serverversion"`
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"`
Peers []wgtypes.PeerConfig
PeerIDs PeerMap `json:"peerids" bson:"peerids" yaml:"peerids"`
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"`
OldPeers []wgtypes.PeerConfig `json:"Peers"`
EndpointDetection bool `json:"endpoint_detection"`
}
type FwRule struct {

View file

@ -252,24 +252,26 @@ type NodeJoinResponse struct {
// ServerConfig - struct for dealing with the server information for a netclient
type ServerConfig struct {
CoreDNSAddr string `yaml:"corednsaddr"`
API string `yaml:"api"`
APIPort string `yaml:"apiport"`
DNSMode string `yaml:"dnsmode"`
Version string `yaml:"version"`
MQPort string `yaml:"mqport"`
MQUserName string `yaml:"mq_username"`
MQPassword string `yaml:"mq_password"`
BrokerType string `yaml:"broker_type"`
Server string `yaml:"server"`
Broker string `yaml:"broker"`
IsPro bool `yaml:"isee" json:"Is_EE"`
TrafficKey []byte `yaml:"traffickey"`
MetricInterval string `yaml:"metric_interval"`
ManageDNS bool `yaml:"manage_dns"`
Stun bool `yaml:"stun"`
StunServers string `yaml:"stun_servers"`
DefaultDomain string `yaml:"default_domain"`
CoreDNSAddr string `yaml:"corednsaddr"`
API string `yaml:"api"`
APIPort string `yaml:"apiport"`
DNSMode string `yaml:"dnsmode"`
Version string `yaml:"version"`
MQPort string `yaml:"mqport"`
MQUserName string `yaml:"mq_username"`
MQPassword string `yaml:"mq_password"`
BrokerType string `yaml:"broker_type"`
Server string `yaml:"server"`
Broker string `yaml:"broker"`
IsPro bool `yaml:"isee" json:"Is_EE"`
TrafficKey []byte `yaml:"traffickey"`
MetricInterval string `yaml:"metric_interval"`
MetricsPort int `yaml:"metrics_port"`
ManageDNS bool `yaml:"manage_dns"`
Stun bool `yaml:"stun"`
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

View file

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

View file

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

View file

@ -96,3 +96,7 @@ MANAGE_DNS=false
OLD_ACL_SUPPORT=true
# if STUN is set to true, hole punch is called
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"
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:],\")
BRANCH=master
if [ $(id -u) -ne 0 ]; then
echo "This script must be run as root"
exit 1
@ -617,7 +617,7 @@ install_netmaker() {
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 CADDY_URL="$BASE_URL/docker/Caddyfile"
if [ "$INSTALL_TYPE" = "pro" ]; then

View file

@ -14,6 +14,8 @@ import (
"github.com/gravitl/netmaker/models"
)
var ServerInfo = GetServerInfo()
// EmqxBrokerType denotes the broker type for EMQX MQTT
const EmqxBrokerType = "emqx"
@ -141,10 +143,12 @@ func GetServerInfo() models.ServerConfig {
cfg.Version = GetVersion()
cfg.IsPro = IsPro
cfg.MetricInterval = GetMetricInterval()
cfg.MetricsPort = GetMetricsPort()
cfg.ManageDNS = GetManageDNS()
cfg.Stun = IsStunEnabled()
cfg.StunServers = GetStunServers()
cfg.DefaultDomain = GetDefaultDomain()
cfg.EndpointDetection = IsEndpointDetectionEnabled()
return cfg
}
@ -654,6 +658,19 @@ func GetMqUserName() string {
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
func GetMetricIntervalInMinutes() time.Duration {
//default 15 minutes

View file

@ -1,6 +1,10 @@
package utils
import "time"
import (
"log/slog"
"runtime"
"time"
)
// RetryStrategy specifies a strategy to retry an operation after waiting a while,
// with hooks for successful and unsuccessful (>=max) tries.
@ -39,3 +43,19 @@ func (rs RetryStrategy) DoStrategy() {
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)
}