From cb4b99ffcb23c1318340ba02dd2b042c957e9698 Mon Sep 17 00:00:00 2001 From: Gabriel de Souza Seibel Date: Fri, 6 Oct 2023 03:09:19 -0300 Subject: [PATCH] [NET-562] Persistent Keep Alive from node to host (#2604) * Move PKA field from models node to host level * Move PKA field from api models node to host level * Adapt logic package to node->host PKA * Adapt migration-related code to node->host PKA * Adapt cli code to node->host PKA * Change host PKA default to 20s * On IfaceDelta, check for PKA on host * On handleHostRegister, set default PKA * Use a default PKA * Use int64 for api host pka * Reorder imports * Don't use host pka in iface delta * Fix ConvertAPIHostToNMHost * Add swagger doc for host PKA field * Fix swagger.yml * Set default PKA only for new hosts * Remove TODO comment * Remove redundant check * Have api-host pka be specified in seconds --- cli/cmd/host/update.go | 6 +++- cli/cmd/node/flags.go | 1 - cli/cmd/node/update.go | 2 -- controllers/enrollmentkeys.go | 60 +++++++++++++++++++++++++-------- controllers/migrate.go | 2 +- logic/hosts.go | 16 +++++---- logic/nodes.go | 3 -- logic/peers.go | 10 +++--- logic/wireguard.go | 1 - migrate/migrate.go | 34 +++++++++++++++++-- models/api_host.go | 51 +++++++++++++++------------- models/api_node.go | 3 -- models/host.go | 63 +++++++++++++++++++---------------- models/node.go | 46 ++++++++++++------------- 14 files changed, 179 insertions(+), 119 deletions(-) diff --git a/cli/cmd/host/update.go b/cli/cmd/host/update.go index 87fdb9fe4..0809f2d45 100644 --- a/cli/cmd/host/update.go +++ b/cli/cmd/host/update.go @@ -5,9 +5,10 @@ import ( "log" "os" + "github.com/spf13/cobra" + "github.com/gravitl/netmaker/cli/functions" "github.com/gravitl/netmaker/models" - "github.com/spf13/cobra" ) var ( @@ -18,6 +19,7 @@ var ( mtu int isStatic bool isDefault bool + keepAlive int ) var hostUpdateCmd = &cobra.Command{ @@ -43,6 +45,7 @@ var hostUpdateCmd = &cobra.Command{ apiHost.MTU = mtu apiHost.IsStatic = isStatic apiHost.IsDefault = isDefault + apiHost.PersistentKeepalive = keepAlive } functions.PrettyPrint(functions.UpdateHost(args[0], apiHost)) }, @@ -54,6 +57,7 @@ func init() { hostUpdateCmd.Flags().StringVar(&name, "name", "", "Host name") hostUpdateCmd.Flags().IntVar(&listenPort, "listen_port", 0, "Listen port of the host") hostUpdateCmd.Flags().IntVar(&mtu, "mtu", 0, "Host MTU size") + hostUpdateCmd.Flags().IntVar(&keepAlive, "keep_alive", 0, "Interval (seconds) in which packets are sent to keep connections open with peers") hostUpdateCmd.Flags().BoolVar(&isStatic, "static", false, "Make Host Static ?") hostUpdateCmd.Flags().BoolVar(&isDefault, "default", false, "Make Host Default ?") rootCmd.AddCommand(hostUpdateCmd) diff --git a/cli/cmd/node/flags.go b/cli/cmd/node/flags.go index 48f2f7495..2ed805d75 100644 --- a/cli/cmd/node/flags.go +++ b/cli/cmd/node/flags.go @@ -11,7 +11,6 @@ var ( name string postUp string postDown string - keepAlive int relayedNodes string egressGatewayRanges string expirationDateTime int diff --git a/cli/cmd/node/update.go b/cli/cmd/node/update.go index e2d2d3836..b8ff74d07 100644 --- a/cli/cmd/node/update.go +++ b/cli/cmd/node/update.go @@ -34,7 +34,6 @@ var nodeUpdateCmd = &cobra.Command{ node.Address = address node.Address6 = address6 node.LocalAddress = localAddress - node.PersistentKeepalive = int32(keepAlive) if relayedNodes != "" { node.RelayedNodes = strings.Split(relayedNodes, ",") } @@ -61,7 +60,6 @@ func init() { nodeUpdateCmd.Flags().StringVar(&name, "name", "", "Node name") nodeUpdateCmd.Flags().StringVar(&postUp, "post_up", "", "Commands to run after node is up `;` separated") nodeUpdateCmd.Flags().StringVar(&postDown, "post_down", "", "Commands to run after node is down `;` separated") - nodeUpdateCmd.Flags().IntVar(&keepAlive, "keep_alive", 0, "Interval in which packets are sent to keep connections open with peers") nodeUpdateCmd.Flags().StringVar(&relayedNodes, "relayed_nodes", "", "relayed nodes if node acts as a relay") nodeUpdateCmd.Flags().StringVar(&egressGatewayRanges, "egress_addrs", "", "Addresses for egressing traffic if node acts as an egress") nodeUpdateCmd.Flags().IntVar(&expirationDateTime, "expiry", 0, "UNIX timestamp after which node will lose access to the network") diff --git a/controllers/enrollmentkeys.go b/controllers/enrollmentkeys.go index 6a8579b1f..33b2c7209 100644 --- a/controllers/enrollmentkeys.go +++ b/controllers/enrollmentkeys.go @@ -7,6 +7,7 @@ import ( "time" "github.com/gorilla/mux" + "github.com/gravitl/netmaker/auth" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logic" @@ -17,10 +18,14 @@ import ( ) func enrollmentKeyHandlers(r *mux.Router) { - r.HandleFunc("/api/v1/enrollment-keys", logic.SecurityCheck(true, http.HandlerFunc(createEnrollmentKey))).Methods(http.MethodPost) - r.HandleFunc("/api/v1/enrollment-keys", logic.SecurityCheck(true, http.HandlerFunc(getEnrollmentKeys))).Methods(http.MethodGet) - r.HandleFunc("/api/v1/enrollment-keys/{keyID}", logic.SecurityCheck(true, http.HandlerFunc(deleteEnrollmentKey))).Methods(http.MethodDelete) - r.HandleFunc("/api/v1/host/register/{token}", http.HandlerFunc(handleHostRegister)).Methods(http.MethodPost) + r.HandleFunc("/api/v1/enrollment-keys", logic.SecurityCheck(true, http.HandlerFunc(createEnrollmentKey))). + Methods(http.MethodPost) + r.HandleFunc("/api/v1/enrollment-keys", logic.SecurityCheck(true, http.HandlerFunc(getEnrollmentKeys))). + Methods(http.MethodGet) + r.HandleFunc("/api/v1/enrollment-keys/{keyID}", logic.SecurityCheck(true, http.HandlerFunc(deleteEnrollmentKey))). + Methods(http.MethodDelete) + r.HandleFunc("/api/v1/host/register/{token}", http.HandlerFunc(handleHostRegister)). + Methods(http.MethodPost) } // swagger:route GET /api/v1/enrollment-keys enrollmentKeys getEnrollmentKeys @@ -70,7 +75,7 @@ func getEnrollmentKeys(w http.ResponseWriter, r *http.Request) { // Responses: // 200: okResponse func deleteEnrollmentKey(w http.ResponseWriter, r *http.Request) { - var params = mux.Vars(r) + params := mux.Vars(r) keyID := params["keyID"] err := logic.DeleteEnrollmentKey(keyID) if err != nil { @@ -94,7 +99,6 @@ func deleteEnrollmentKey(w http.ResponseWriter, r *http.Request) { // Responses: // 200: EnrollmentKey func createEnrollmentKey(w http.ResponseWriter, r *http.Request) { - var enrollmentKeyBody models.APIEnrollmentKey err := json.NewDecoder(r.Body).Decode(&enrollmentKeyBody) @@ -109,7 +113,13 @@ func createEnrollmentKey(w http.ResponseWriter, r *http.Request) { newTime = time.Unix(enrollmentKeyBody.Expiration, 0) } - newEnrollmentKey, err := logic.CreateEnrollmentKey(enrollmentKeyBody.UsesRemaining, newTime, enrollmentKeyBody.Networks, enrollmentKeyBody.Tags, enrollmentKeyBody.Unlimited) + newEnrollmentKey, err := logic.CreateEnrollmentKey( + enrollmentKeyBody.UsesRemaining, + newTime, + enrollmentKeyBody.Networks, + enrollmentKeyBody.Tags, + enrollmentKeyBody.Unlimited, + ) if err != nil { logger.Log(0, r.Header.Get("user"), "failed to create enrollment key:", err.Error()) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) @@ -138,7 +148,7 @@ func createEnrollmentKey(w http.ResponseWriter, r *http.Request) { // Responses: // 200: RegisterResponse func handleHostRegister(w http.ResponseWriter, r *http.Request) { - var params = mux.Vars(r) + params := mux.Vars(r) token := params["token"] logger.Log(0, "received registration attempt with token", token) // check if token exists @@ -156,7 +166,6 @@ func handleHostRegister(w http.ResponseWriter, r *http.Request) { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } - hostExists := false // re-register host with turn just in case. if servercfg.IsUsingTurn() { err = logic.RegisterHostWithTurn(newHost.ID.String(), newHost.HostPass) @@ -165,9 +174,20 @@ func handleHostRegister(w http.ResponseWriter, r *http.Request) { } } // check if host already exists + hostExists := false if hostExists = logic.HostExists(&newHost); hostExists && len(enrollmentKey.Networks) == 0 { - logger.Log(0, "host", newHost.ID.String(), newHost.Name, "attempted to re-register with no networks") - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("host already exists"), "badrequest")) + logger.Log( + 0, + "host", + newHost.ID.String(), + newHost.Name, + "attempted to re-register with no networks", + ) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("host already exists"), "badrequest"), + ) return } // version check @@ -190,11 +210,16 @@ func handleHostRegister(w http.ResponseWriter, r *http.Request) { // use the token if ok := logic.TryToUseEnrollmentKey(enrollmentKey); !ok { logger.Log(0, "host", newHost.ID.String(), newHost.Name, "failed registration") - logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("invalid enrollment key"), "badrequest")) + logic.ReturnErrorResponse( + w, + r, + logic.FormatError(fmt.Errorf("invalid enrollment key"), "badrequest"), + ) return } hostPass := newHost.HostPass if !hostExists { + newHost.PersistentKeepalive = models.DefaultPersistentKeepAlive // register host logic.CheckHostPorts(&newHost) // create EMQX credentials and ACLs for host @@ -209,14 +234,21 @@ func handleHostRegister(w http.ResponseWriter, r *http.Request) { } } if err = logic.CreateHost(&newHost); err != nil { - logger.Log(0, "host", newHost.ID.String(), newHost.Name, "failed registration -", err.Error()) + logger.Log( + 0, + "host", + newHost.ID.String(), + newHost.Name, + "failed registration -", + err.Error(), + ) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } } else { // need to revise the list of networks from key // based on the ones host currently has - var networksToAdd = []string{} + networksToAdd := []string{} currentNets := logic.GetHostNetworks(newHost.ID.String()) for _, newNet := range enrollmentKey.Networks { if !logic.StringSliceContains(currentNets, newNet) { diff --git a/controllers/migrate.go b/controllers/migrate.go index eea158fbf..148295951 100644 --- a/controllers/migrate.go +++ b/controllers/migrate.go @@ -65,6 +65,7 @@ func migrate(w http.ResponseWriter, r *http.Request) { host.Name = data.HostName host.HostPass = data.Password host.OS = data.OS + host.PersistentKeepalive = time.Duration(legacy.PersistentKeepalive) if err := logic.CreateHost(&host); err != nil { slog.Error("create host", "error", err) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) @@ -202,7 +203,6 @@ func convertLegacyNode(legacy models.LegacyNode, hostID uuid.UUID) models.Node { node.IsRelay = false node.RelayedNodes = []string{} node.DNSOn = models.ParseBool(legacy.DNSOn) - node.PersistentKeepalive = time.Duration(int64(time.Second) * int64(legacy.PersistentKeepalive)) node.LastModified = time.Now() node.ExpirationDateTime = time.Unix(legacy.ExpirationDateTime, 0) node.EgressGatewayNatEnabled = models.ParseBool(legacy.EgressGatewayNatEnabled) diff --git a/logic/hosts.go b/logic/hosts.go index e17c6f1e7..2137706ff 100644 --- a/logic/hosts.go +++ b/logic/hosts.go @@ -13,11 +13,12 @@ import ( "github.com/devilcove/httpclient" "github.com/google/uuid" + "golang.org/x/crypto/bcrypt" + "github.com/gravitl/netmaker/database" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/servercfg" - "golang.org/x/crypto/bcrypt" ) var ( @@ -66,6 +67,7 @@ func deleteHostFromCache(hostID string) { delete(hostsCacheMap, hostID) hostCacheMutex.Unlock() } + func loadHostsIntoCache(hMap map[string]models.Host) { hostCacheMutex.Lock() hostsCacheMap = hMap @@ -79,7 +81,6 @@ const ( // GetAllHosts - returns all hosts in flat list or error func GetAllHosts() ([]models.Host, error) { - currHosts := getHostsFromCache() if len(currHosts) != 0 { return currHosts, nil @@ -139,7 +140,6 @@ func GetHostsMap() (map[string]models.Host, error) { // GetHost - gets a host from db given id func GetHost(hostid string) (*models.Host, error) { - if host, ok := getHostFromCache(hostid); ok { return &host, nil } @@ -217,11 +217,13 @@ func UpdateHost(newHost, currentHost *models.Host) { newHost.ListenPort = currentHost.ListenPort } + if newHost.PersistentKeepalive == 0 { + newHost.PersistentKeepalive = currentHost.PersistentKeepalive + } } // UpdateHostFromClient - used for updating host on server with update recieved from client func UpdateHostFromClient(newHost, currHost *models.Host) (sendPeerUpdate bool) { - if newHost.PublicKey != currHost.PublicKey { currHost.PublicKey = newHost.PublicKey sendPeerUpdate = true @@ -230,7 +232,8 @@ func UpdateHostFromClient(newHost, currHost *models.Host) (sendPeerUpdate bool) currHost.ListenPort = newHost.ListenPort sendPeerUpdate = true } - if newHost.WgPublicListenPort != 0 && currHost.WgPublicListenPort != newHost.WgPublicListenPort { + if newHost.WgPublicListenPort != 0 && + currHost.WgPublicListenPort != newHost.WgPublicListenPort { currHost.WgPublicListenPort = newHost.WgPublicListenPort sendPeerUpdate = true } @@ -488,7 +491,7 @@ func CheckHostPorts(h *models.Host) { } for _, host := range hosts { if host.ID.String() == h.ID.String() { - //skip self + // skip self continue } if !host.EndpointIP.Equal(h.EndpointIP) { @@ -503,7 +506,6 @@ func CheckHostPorts(h *models.Host) { h.ListenPort = minPort } } - } // HostExists - checks if given host already exists diff --git a/logic/nodes.go b/logic/nodes.go index 6b843fbad..c9cf8da01 100644 --- a/logic/nodes.go +++ b/logic/nodes.go @@ -350,9 +350,6 @@ func SetNodeDefaults(node *models.Node) { node.DefaultACL = parentNetwork.DefaultACL } - if node.PersistentKeepalive == 0 { - node.PersistentKeepalive = time.Second * time.Duration(parentNetwork.DefaultKeepalive) - } node.SetLastModified() node.SetLastCheckIn() node.SetDefaultConnected() diff --git a/logic/peers.go b/logic/peers.go index 79d94e9ce..ada95ac91 100644 --- a/logic/peers.go +++ b/logic/peers.go @@ -64,7 +64,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N } relayPeer := wgtypes.PeerConfig{ PublicKey: relayHost.PublicKey, - PersistentKeepaliveInterval: &relayNode.PersistentKeepalive, + PersistentKeepaliveInterval: &relayHost.PersistentKeepalive, ReplaceAllowedIPs: true, AllowedIPs: GetAllowedIPs(&node, &relayNode, nil), } @@ -111,7 +111,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N peer := peer if peer.ID.String() == node.ID.String() { logger.Log(2, "peer update, skipping self") - //skip yourself + // skip yourself continue } @@ -122,7 +122,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N } peerConfig := wgtypes.PeerConfig{ PublicKey: peerHost.PublicKey, - PersistentKeepaliveInterval: &peer.PersistentKeepalive, + PersistentKeepaliveInterval: &peerHost.PersistentKeepalive, ReplaceAllowedIPs: true, } if peer.IsEgressGateway { @@ -390,7 +390,7 @@ func GetEgressIPs(peer *models.Node) []net.IPNet { logger.Log(0, "error retrieving host for peer", peer.ID.String(), err.Error()) } - //check for internet gateway + // check for internet gateway internetGateway := false if slices.Contains(peer.EgressGatewayRanges, "0.0.0.0/0") || slices.Contains(peer.EgressGatewayRanges, "::/0") { internetGateway = true @@ -439,7 +439,7 @@ func getNodeAllowedIPs(peer, node *models.Node) []net.IPNet { } // handle egress gateway peers if peer.IsEgressGateway { - //hasGateway = true + // hasGateway = true egressIPs := GetEgressIPs(peer) allowedips = append(allowedips, egressIPs...) } diff --git a/logic/wireguard.go b/logic/wireguard.go index 7ef6cbabf..0828ff6ff 100644 --- a/logic/wireguard.go +++ b/logic/wireguard.go @@ -12,7 +12,6 @@ func IfaceDelta(currentNode *models.Node, newNode *models.Node) bool { newNode.IsEgressGateway != currentNode.IsEgressGateway || newNode.IsIngressGateway != currentNode.IsIngressGateway || newNode.IsRelay != currentNode.IsRelay || - newNode.PersistentKeepalive != currentNode.PersistentKeepalive || newNode.DNSOn != currentNode.DNSOn || newNode.Connected != currentNode.Connected { return true diff --git a/migrate/migrate.go b/migrate/migrate.go index 22b70251d..371ffe30c 100644 --- a/migrate/migrate.go +++ b/migrate/migrate.go @@ -3,17 +3,19 @@ package migrate import ( "encoding/json" + "golang.org/x/exp/slog" + "github.com/gravitl/netmaker/database" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/models" - "golang.org/x/exp/slog" ) // Run - runs all migrations func Run() { updateEnrollmentKeys() assignSuperAdmin() + updateHosts() } func assignSuperAdmin() { @@ -37,7 +39,13 @@ func assignSuperAdmin() { user.IsAdmin = false err = logic.UpsertUser(*user) if err != nil { - slog.Error("error updating user to superadmin", "user", user.UserName, "error", err.Error()) + slog.Error( + "error updating user to superadmin", + "user", + user.UserName, + "error", + err.Error(), + ) continue } else { createdSuperAdmin = true @@ -49,7 +57,6 @@ func assignSuperAdmin() { if !createdSuperAdmin { slog.Error("failed to create superadmin!!") } - } func updateEnrollmentKeys() { @@ -87,3 +94,24 @@ func updateEnrollmentKeys() { } } + +func updateHosts() { + rows, err := database.FetchRecords(database.HOSTS_TABLE_NAME) + if err != nil { + logger.Log(0, "failed to fetch database records for hosts") + } + for _, row := range rows { + var host models.Host + if err := json.Unmarshal([]byte(row), &host); err != nil { + logger.Log(0, "failed to unmarshal database row to host", "row", row) + continue + } + if host.PersistentKeepalive == 0 { + host.PersistentKeepalive = models.DefaultPersistentKeepAlive + if err := logic.UpsertHost(&host); err != nil { + logger.Log(0, "failed to upsert host", host.ID.String()) + continue + } + } + } +} diff --git a/models/api_host.go b/models/api_host.go index 4558a984b..7dd9fdf9e 100644 --- a/models/api_host.go +++ b/models/api_host.go @@ -3,33 +3,35 @@ package models import ( "net" "strings" + "time" ) // ApiHost - the host struct for API usage type ApiHost struct { - ID string `json:"id"` - Verbosity int `json:"verbosity"` - FirewallInUse string `json:"firewallinuse"` - Version string `json:"version"` - Name string `json:"name"` - OS string `json:"os"` - Debug bool `json:"debug"` - IsStatic bool `json:"isstatic"` - ListenPort int `json:"listenport"` - WgPublicListenPort int `json:"wg_public_listen_port" yaml:"wg_public_listen_port"` - MTU int `json:"mtu" yaml:"mtu"` - Interfaces []Iface `json:"interfaces" yaml:"interfaces"` - DefaultInterface string `json:"defaultinterface" yaml:"defautlinterface"` - EndpointIP string `json:"endpointip" yaml:"endpointip"` - PublicKey string `json:"publickey"` - MacAddress string `json:"macaddress"` - Nodes []string `json:"nodes"` - IsDefault bool `json:"isdefault" yaml:"isdefault"` - IsRelayed bool `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"` - RelayedBy string `json:"relayed_by" bson:"relayed_by" yaml:"relayed_by"` - IsRelay bool `json:"isrelay" bson:"isrelay" yaml:"isrelay"` - RelayedHosts []string `json:"relay_hosts" bson:"relay_hosts" yaml:"relay_hosts"` - NatType string `json:"nat_type" yaml:"nat_type"` + ID string `json:"id"` + Verbosity int `json:"verbosity"` + FirewallInUse string `json:"firewallinuse"` + Version string `json:"version"` + Name string `json:"name"` + OS string `json:"os"` + Debug bool `json:"debug"` + IsStatic bool `json:"isstatic"` + ListenPort int `json:"listenport"` + WgPublicListenPort int `json:"wg_public_listen_port" yaml:"wg_public_listen_port"` + MTU int `json:"mtu" yaml:"mtu"` + Interfaces []Iface `json:"interfaces" yaml:"interfaces"` + DefaultInterface string `json:"defaultinterface" yaml:"defautlinterface"` + EndpointIP string `json:"endpointip" yaml:"endpointip"` + PublicKey string `json:"publickey"` + MacAddress string `json:"macaddress"` + Nodes []string `json:"nodes"` + IsDefault bool `json:"isdefault" yaml:"isdefault"` + IsRelayed bool `json:"isrelayed" yaml:"isrelayed" bson:"isrelayed"` + RelayedBy string `json:"relayed_by" yaml:"relayed_by" bson:"relayed_by"` + IsRelay bool `json:"isrelay" yaml:"isrelay" bson:"isrelay"` + RelayedHosts []string `json:"relay_hosts" yaml:"relay_hosts" bson:"relay_hosts"` + NatType string `json:"nat_type" yaml:"nat_type"` + PersistentKeepalive int `json:"persistentkeepalive" yaml:"persistentkeepalive"` } // Host.ConvertNMHostToAPI - converts a Netmaker host to an API editable host @@ -57,6 +59,7 @@ func (h *Host) ConvertNMHostToAPI() *ApiHost { a.Version = h.Version a.IsDefault = h.IsDefault a.NatType = h.NatType + a.PersistentKeepalive = int(h.PersistentKeepalive.Seconds()) return &a } @@ -94,6 +97,6 @@ func (a *ApiHost) ConvertAPIHostToNMHost(currentHost *Host) *Host { h.IsDefault = a.IsDefault h.NatType = currentHost.NatType h.TurnEndpoint = currentHost.TurnEndpoint - + h.PersistentKeepalive = time.Duration(a.PersistentKeepalive) * time.Second return &h } diff --git a/models/api_node.go b/models/api_node.go index 843b0bf23..5dea54ae3 100644 --- a/models/api_node.go +++ b/models/api_node.go @@ -15,7 +15,6 @@ type ApiNode struct { Address6 string `json:"address6" validate:"omitempty,ipv6"` LocalAddress string `json:"localaddress" validate:"omitempty,ipv4"` AllowedIPs []string `json:"allowedips"` - PersistentKeepalive int32 `json:"persistentkeepalive"` LastModified int64 `json:"lastmodified"` ExpirationDateTime int64 `json:"expdatetime"` LastCheckIn int64 `json:"lastcheckin"` @@ -68,7 +67,6 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node { convertedNode.IngressDNS = a.IngressDns convertedNode.EgressGatewayRequest = currentNode.EgressGatewayRequest convertedNode.EgressGatewayNatEnabled = currentNode.EgressGatewayNatEnabled - convertedNode.PersistentKeepalive = time.Second * time.Duration(a.PersistentKeepalive) convertedNode.RelayedNodes = a.RelayedNodes convertedNode.DefaultACL = a.DefaultACL convertedNode.OwnerID = currentNode.OwnerID @@ -127,7 +125,6 @@ func (nm *Node) ConvertToAPINode() *ApiNode { if isEmptyAddr(apiNode.LocalAddress) { apiNode.LocalAddress = "" } - apiNode.PersistentKeepalive = int32(nm.PersistentKeepalive.Seconds()) apiNode.LastModified = nm.LastModified.Unix() apiNode.LastCheckIn = nm.LastCheckIn.Unix() apiNode.LastPeerUpdate = nm.LastPeerUpdate.Unix() diff --git a/models/host.go b/models/host.go index bfab10027..4a2715b50 100644 --- a/models/host.go +++ b/models/host.go @@ -3,6 +3,7 @@ package models import ( "net" "net/netip" + "time" "github.com/google/uuid" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" @@ -33,38 +34,42 @@ var NAT_Types = struct { } // WIREGUARD_INTERFACE name of wireguard interface -const WIREGUARD_INTERFACE = "netmaker" +const ( + WIREGUARD_INTERFACE = "netmaker" + DefaultPersistentKeepAlive = 20 * time.Second +) // Host - represents a host on the network type Host struct { - ID uuid.UUID `json:"id" yaml:"id"` - Verbosity int `json:"verbosity" yaml:"verbosity"` - FirewallInUse string `json:"firewallinuse" yaml:"firewallinuse"` - Version string `json:"version" yaml:"version"` - IPForwarding bool `json:"ipforwarding" yaml:"ipforwarding"` - DaemonInstalled bool `json:"daemoninstalled" yaml:"daemoninstalled"` - AutoUpdate bool `json:"autoupdate" yaml:"autoupdate"` - HostPass string `json:"hostpass" yaml:"hostpass"` - Name string `json:"name" yaml:"name"` - OS string `json:"os" yaml:"os"` - Interface string `json:"interface" yaml:"interface"` - Debug bool `json:"debug" yaml:"debug"` - ListenPort int `json:"listenport" yaml:"listenport"` - WgPublicListenPort int `json:"wg_public_listen_port" yaml:"wg_public_listen_port"` - MTU int `json:"mtu" yaml:"mtu"` - PublicKey wgtypes.Key `json:"publickey" yaml:"publickey"` - MacAddress net.HardwareAddr `json:"macaddress" yaml:"macaddress"` - TrafficKeyPublic []byte `json:"traffickeypublic" yaml:"traffickeypublic"` - Nodes []string `json:"nodes" yaml:"nodes"` - Interfaces []Iface `json:"interfaces" yaml:"interfaces"` - DefaultInterface string `json:"defaultinterface" yaml:"defaultinterface"` - EndpointIP net.IP `json:"endpointip" yaml:"endpointip"` - IsDocker bool `json:"isdocker" yaml:"isdocker"` - IsK8S bool `json:"isk8s" yaml:"isk8s"` - IsStatic bool `json:"isstatic" yaml:"isstatic"` - IsDefault bool `json:"isdefault" yaml:"isdefault"` - NatType string `json:"nat_type,omitempty" yaml:"nat_type,omitempty"` - TurnEndpoint *netip.AddrPort `json:"turn_endpoint,omitempty" yaml:"turn_endpoint,omitempty"` + ID uuid.UUID `json:"id" yaml:"id"` + Verbosity int `json:"verbosity" yaml:"verbosity"` + FirewallInUse string `json:"firewallinuse" yaml:"firewallinuse"` + Version string `json:"version" yaml:"version"` + IPForwarding bool `json:"ipforwarding" yaml:"ipforwarding"` + DaemonInstalled bool `json:"daemoninstalled" yaml:"daemoninstalled"` + AutoUpdate bool `json:"autoupdate" yaml:"autoupdate"` + HostPass string `json:"hostpass" yaml:"hostpass"` + Name string `json:"name" yaml:"name"` + OS string `json:"os" yaml:"os"` + Interface string `json:"interface" yaml:"interface"` + Debug bool `json:"debug" yaml:"debug"` + ListenPort int `json:"listenport" yaml:"listenport"` + WgPublicListenPort int `json:"wg_public_listen_port" yaml:"wg_public_listen_port"` + MTU int `json:"mtu" yaml:"mtu"` + PublicKey wgtypes.Key `json:"publickey" yaml:"publickey"` + MacAddress net.HardwareAddr `json:"macaddress" yaml:"macaddress"` + TrafficKeyPublic []byte `json:"traffickeypublic" yaml:"traffickeypublic"` + Nodes []string `json:"nodes" yaml:"nodes"` + Interfaces []Iface `json:"interfaces" yaml:"interfaces"` + DefaultInterface string `json:"defaultinterface" yaml:"defaultinterface"` + EndpointIP net.IP `json:"endpointip" yaml:"endpointip"` + IsDocker bool `json:"isdocker" yaml:"isdocker"` + IsK8S bool `json:"isk8s" yaml:"isk8s"` + IsStatic bool `json:"isstatic" yaml:"isstatic"` + IsDefault bool `json:"isdefault" yaml:"isdefault"` + NatType string `json:"nat_type,omitempty" yaml:"nat_type,omitempty"` + TurnEndpoint *netip.AddrPort `json:"turn_endpoint,omitempty" yaml:"turn_endpoint,omitempty"` + PersistentKeepalive time.Duration `json:"persistentkeepalive" yaml:"persistentkeepalive"` } // FormatBool converts a boolean to a [yes|no] string diff --git a/models/node.go b/models/node.go index b011321ef..777c6aaf0 100644 --- a/models/node.go +++ b/models/node.go @@ -54,28 +54,27 @@ type Iface struct { // CommonNode - represents a commonn node data elements shared by netmaker and netclient type CommonNode struct { - ID uuid.UUID `json:"id" yaml:"id"` - HostID uuid.UUID `json:"hostid" yaml:"hostid"` - Network string `json:"network" yaml:"network"` - NetworkRange net.IPNet `json:"networkrange" yaml:"networkrange"` - NetworkRange6 net.IPNet `json:"networkrange6" yaml:"networkrange6"` - InternetGateway *net.UDPAddr `json:"internetgateway" yaml:"internetgateway"` - Server string `json:"server" yaml:"server"` - Connected bool `json:"connected" yaml:"connected"` - Address net.IPNet `json:"address" yaml:"address"` - Address6 net.IPNet `json:"address6" yaml:"address6"` - Action string `json:"action" yaml:"action"` - LocalAddress net.IPNet `json:"localaddress" yaml:"localaddress"` - IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"` - EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"` - IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"` - IsRelayed bool `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"` - RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"` - IsRelay bool `json:"isrelay" bson:"isrelay" yaml:"isrelay"` - RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"` - IngressDNS string `json:"ingressdns" yaml:"ingressdns"` - DNSOn bool `json:"dnson" yaml:"dnson"` - PersistentKeepalive time.Duration `json:"persistentkeepalive" yaml:"persistentkeepalive"` + ID uuid.UUID `json:"id" yaml:"id"` + HostID uuid.UUID `json:"hostid" yaml:"hostid"` + Network string `json:"network" yaml:"network"` + NetworkRange net.IPNet `json:"networkrange" yaml:"networkrange"` + NetworkRange6 net.IPNet `json:"networkrange6" yaml:"networkrange6"` + InternetGateway *net.UDPAddr `json:"internetgateway" yaml:"internetgateway"` + Server string `json:"server" yaml:"server"` + Connected bool `json:"connected" yaml:"connected"` + Address net.IPNet `json:"address" yaml:"address"` + Address6 net.IPNet `json:"address6" yaml:"address6"` + Action string `json:"action" yaml:"action"` + LocalAddress net.IPNet `json:"localaddress" yaml:"localaddress"` + IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"` + EgressGatewayRanges []string `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"` + IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"` + IsRelayed bool `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"` + RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"` + IsRelay bool `json:"isrelay" bson:"isrelay" yaml:"isrelay"` + RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"` + IngressDNS string `json:"ingressdns" yaml:"ingressdns"` + DNSOn bool `json:"dnson" yaml:"dnson"` } // Node - a model of a network node @@ -369,9 +368,6 @@ func (newNode *Node) Fill(currentNode *Node, isPro bool) { // TODO add new field if newNode.Address6.String() == "" { newNode.Address6 = currentNode.Address6 } - if newNode.PersistentKeepalive < 0 { - newNode.PersistentKeepalive = currentNode.PersistentKeepalive - } if newNode.LastModified != currentNode.LastModified { newNode.LastModified = currentNode.LastModified }