diff --git a/compose/docker-compose.yml b/compose/docker-compose.yml index 5e6b1cc73..054936afc 100644 --- a/compose/docker-compose.yml +++ b/compose/docker-compose.yml @@ -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 diff --git a/config/config.go b/config/config.go index 06e8ee397..dac7e186f 100644 --- a/config/config.go +++ b/config/config.go @@ -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"` diff --git a/controllers/hosts.go b/controllers/hosts.go index 5458a1797..d41ce1cd9 100644 --- a/controllers/hosts.go +++ b/controllers/hosts.go @@ -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) diff --git a/logic/peers.go b/logic/peers.go index f5d548ba0..31412100b 100644 --- a/logic/peers.go +++ b/logic/peers.go @@ -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 } diff --git a/logic/util.go b/logic/util.go index bff2ced67..22ee3f097 100644 --- a/logic/util.go +++ b/logic/util.go @@ -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) { diff --git a/models/metrics.go b/models/metrics.go index 2e70a1780..c364c18e4 100644 --- a/models/metrics.go +++ b/models/metrics.go @@ -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 diff --git a/models/mqtt.go b/models/mqtt.go index c5921f381..4b7ce10aa 100644 --- a/models/mqtt.go +++ b/models/mqtt.go @@ -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 { diff --git a/models/structs.go b/models/structs.go index e929e7fc7..49655a6e6 100644 --- a/models/structs.go +++ b/models/structs.go @@ -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 diff --git a/mq/handlers.go b/mq/handlers.go index 129133268..3b33bb69d 100644 --- a/mq/handlers.go +++ b/mq/handlers.go @@ -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 diff --git a/mq/publishers.go b/mq/publishers.go index 28ef1935d..cbebf60f8 100644 --- a/mq/publishers.go +++ b/mq/publishers.go @@ -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 { diff --git a/scripts/netmaker.default.env b/scripts/netmaker.default.env index 806c3765d..e5de8d35c 100644 --- a/scripts/netmaker.default.env +++ b/scripts/netmaker.default.env @@ -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 diff --git a/scripts/nm-quick.sh b/scripts/nm-quick.sh index 86a083c5e..3c79dff8e 100755 --- a/scripts/nm-quick.sh +++ b/scripts/nm-quick.sh @@ -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 diff --git a/servercfg/serverconf.go b/servercfg/serverconf.go index 267a08bf6..f00723af2 100644 --- a/servercfg/serverconf.go +++ b/servercfg/serverconf.go @@ -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 diff --git a/utils/utils.go b/utils/utils.go index cb8c41d89..f755dceb3 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -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) +}