|
@@ -3,14 +3,22 @@ package logic
|
|
|
import (
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
+ "net"
|
|
|
"slices"
|
|
|
"sort"
|
|
|
"time"
|
|
|
|
|
|
+ "github.com/google/uuid"
|
|
|
"github.com/gravitl/netmaker/database"
|
|
|
"github.com/gravitl/netmaker/logger"
|
|
|
"github.com/gravitl/netmaker/models"
|
|
|
"github.com/gravitl/netmaker/servercfg"
|
|
|
+ "golang.org/x/exp/slog"
|
|
|
+)
|
|
|
+
|
|
|
+var (
|
|
|
+ IPv4Network = "0.0.0.0/0"
|
|
|
+ IPv6Network = "::/0"
|
|
|
)
|
|
|
|
|
|
// IsInternetGw - checks if node is acting as internet gw
|
|
@@ -267,9 +275,6 @@ func DeleteIngressGateway(nodeid string) (models.Node, []models.ExtClient, error
|
|
|
logger.Log(3, "deleting ingress gateway")
|
|
|
node.LastModified = time.Now().UTC()
|
|
|
node.IsIngressGateway = false
|
|
|
- if !servercfg.IsPro {
|
|
|
- node.IsInternetGateway = false
|
|
|
- }
|
|
|
delete(node.Tags, models.TagID(fmt.Sprintf("%s.%s", node.Network, models.GwTagName)))
|
|
|
node.IngressGatewayRange = ""
|
|
|
node.Metadata = ""
|
|
@@ -316,3 +321,157 @@ func IsUserAllowedAccessToExtClient(username string, client models.ExtClient) bo
|
|
|
}
|
|
|
return true
|
|
|
}
|
|
|
+
|
|
|
+func ValidateInetGwReq(inetNode models.Node, req models.InetNodeReq, update bool) error {
|
|
|
+ inetHost, err := GetHost(inetNode.HostID.String())
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if inetHost.FirewallInUse == models.FIREWALL_NONE {
|
|
|
+ return errors.New("iptables or nftables needs to be installed")
|
|
|
+ }
|
|
|
+ if inetNode.InternetGwID != "" {
|
|
|
+ return fmt.Errorf("node %s is using a internet gateway already", inetHost.Name)
|
|
|
+ }
|
|
|
+ if inetNode.IsRelayed {
|
|
|
+ return fmt.Errorf("node %s is being relayed", inetHost.Name)
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, clientNodeID := range req.InetNodeClientIDs {
|
|
|
+ clientNode, err := GetNodeByID(clientNodeID)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if clientNode.IsFailOver {
|
|
|
+ return errors.New("failover node cannot be set to use internet gateway")
|
|
|
+ }
|
|
|
+ clientHost, err := GetHost(clientNode.HostID.String())
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if clientHost.IsDefault {
|
|
|
+ return errors.New("default host cannot be set to use internet gateway")
|
|
|
+ }
|
|
|
+ if clientHost.OS != models.OS_Types.Linux && clientHost.OS != models.OS_Types.Windows {
|
|
|
+ return errors.New("can only attach linux or windows machine to a internet gateway")
|
|
|
+ }
|
|
|
+ if clientNode.IsInternetGateway {
|
|
|
+ return fmt.Errorf("node %s acting as internet gateway cannot use another internet gateway", clientHost.Name)
|
|
|
+ }
|
|
|
+ if update {
|
|
|
+ if clientNode.InternetGwID != "" && clientNode.InternetGwID != inetNode.ID.String() {
|
|
|
+ return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if clientNode.InternetGwID != "" {
|
|
|
+ return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if clientNode.FailedOverBy != uuid.Nil {
|
|
|
+ ResetFailedOverPeer(&clientNode)
|
|
|
+ }
|
|
|
+
|
|
|
+ if clientNode.IsRelayed && clientNode.RelayedBy != inetNode.ID.String() {
|
|
|
+ return fmt.Errorf("node %s is being relayed", clientHost.Name)
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, nodeID := range clientHost.Nodes {
|
|
|
+ node, err := GetNodeByID(nodeID)
|
|
|
+ if err != nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if node.InternetGwID != "" && node.InternetGwID != inetNode.ID.String() {
|
|
|
+ return errors.New("nodes on same host cannot use different internet gateway")
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// SetInternetGw - sets the node as internet gw based on flag bool
|
|
|
+func SetInternetGw(node *models.Node, req models.InetNodeReq) {
|
|
|
+ node.IsInternetGateway = true
|
|
|
+ node.InetNodeReq = req
|
|
|
+ for _, clientNodeID := range req.InetNodeClientIDs {
|
|
|
+ clientNode, err := GetNodeByID(clientNodeID)
|
|
|
+ if err != nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ clientNode.InternetGwID = node.ID.String()
|
|
|
+ UpsertNode(&clientNode)
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func UnsetInternetGw(node *models.Node) {
|
|
|
+ nodes, err := GetNetworkNodes(node.Network)
|
|
|
+ if err != nil {
|
|
|
+ slog.Error("failed to get network nodes", "network", node.Network, "error", err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for _, clientNode := range nodes {
|
|
|
+ if node.ID.String() == clientNode.InternetGwID {
|
|
|
+ clientNode.InternetGwID = ""
|
|
|
+ UpsertNode(&clientNode)
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ node.IsInternetGateway = false
|
|
|
+ node.InetNodeReq = models.InetNodeReq{}
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+func SetDefaultGwForRelayedUpdate(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
|
|
|
+ if relay.InternetGwID != "" {
|
|
|
+ relayedHost, err := GetHost(relayed.HostID.String())
|
|
|
+ if err != nil {
|
|
|
+ return peerUpdate
|
|
|
+ }
|
|
|
+ peerUpdate.ChangeDefaultGw = true
|
|
|
+ peerUpdate.DefaultGwIp = relay.Address.IP
|
|
|
+ if peerUpdate.DefaultGwIp == nil || relayedHost.EndpointIP == nil {
|
|
|
+ peerUpdate.DefaultGwIp = relay.Address6.IP
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ return peerUpdate
|
|
|
+}
|
|
|
+
|
|
|
+func SetDefaultGw(node models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
|
|
|
+ if node.InternetGwID != "" {
|
|
|
+
|
|
|
+ inetNode, err := GetNodeByID(node.InternetGwID)
|
|
|
+ if err != nil {
|
|
|
+ return peerUpdate
|
|
|
+ }
|
|
|
+ host, err := GetHost(node.HostID.String())
|
|
|
+ if err != nil {
|
|
|
+ return peerUpdate
|
|
|
+ }
|
|
|
+
|
|
|
+ peerUpdate.ChangeDefaultGw = true
|
|
|
+ peerUpdate.DefaultGwIp = inetNode.Address.IP
|
|
|
+ if peerUpdate.DefaultGwIp == nil || host.EndpointIP == nil {
|
|
|
+ peerUpdate.DefaultGwIp = inetNode.Address6.IP
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return peerUpdate
|
|
|
+}
|
|
|
+
|
|
|
+// GetAllowedIpForInetNodeClient - get inet cidr for node using a inet gw
|
|
|
+func GetAllowedIpForInetNodeClient(node, peer *models.Node) []net.IPNet {
|
|
|
+ var allowedips = []net.IPNet{}
|
|
|
+
|
|
|
+ if peer.Address.IP != nil {
|
|
|
+ _, ipnet, _ := net.ParseCIDR(IPv4Network)
|
|
|
+ allowedips = append(allowedips, *ipnet)
|
|
|
+ }
|
|
|
+
|
|
|
+ if peer.Address6.IP != nil {
|
|
|
+ _, ipnet, _ := net.ParseCIDR(IPv6Network)
|
|
|
+ allowedips = append(allowedips, *ipnet)
|
|
|
+ }
|
|
|
+
|
|
|
+ return allowedips
|
|
|
+}
|