| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 | package logicimport (	"errors"	"fmt"	"net"	"github.com/google/uuid"	"github.com/gravitl/netmaker/logic"	"github.com/gravitl/netmaker/models"	"golang.org/x/exp/slog")const (	IPv4Network = "0.0.0.0/0"	IPv6Network = "::/0")func ValidateInetGwReq(inetNode models.Node, req models.InetNodeReq, update bool) error {	inetHost, err := logic.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.EgressDetails.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 := logic.GetNodeByID(clientNodeID)		if err != nil {			return err		}		if clientNode.IsFailOver {			return errors.New("failover node cannot be set to use internet gateway")		}		clientHost, err := logic.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.EgressDetails.IsInternetGateway {			return fmt.Errorf("node %s acting as internet gateway cannot use another internet gateway", clientHost.Name)		}		if update {			if clientNode.EgressDetails.InternetGwID != "" && clientNode.EgressDetails.InternetGwID != inetNode.ID.String() {				return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)			}		} else {			if clientNode.EgressDetails.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 := logic.GetNodeByID(nodeID)			if err != nil {				continue			}			if node.EgressDetails.InternetGwID != "" && node.EgressDetails.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 boolfunc SetInternetGw(node *models.Node, req models.InetNodeReq) {	node.EgressDetails.IsInternetGateway = true	node.EgressDetails.InetNodeReq = req	for _, clientNodeID := range req.InetNodeClientIDs {		clientNode, err := logic.GetNodeByID(clientNodeID)		if err != nil {			continue		}		clientNode.EgressDetails.InternetGwID = node.ID.String()		logic.UpsertNode(&clientNode)	}}func UnsetInternetGw(node *models.Node) {	nodes, err := logic.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.EgressDetails.InternetGwID {			clientNode.EgressDetails.InternetGwID = ""			logic.UpsertNode(&clientNode)		}	}	node.EgressDetails.IsInternetGateway = false	node.EgressDetails.InetNodeReq = models.InetNodeReq{}}func SetDefaultGwForRelayedUpdate(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {	if relay.EgressDetails.InternetGwID != "" {		relayedHost, err := logic.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.EgressDetails.InternetGwID != "" {		inetNode, err := logic.GetNodeByID(node.EgressDetails.InternetGwID)		if err != nil {			return peerUpdate		}		host, err := logic.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}// GetNetworkIngresses - gets the gateways of a networkfunc GetNetworkIngresses(network string) ([]models.Node, error) {	var ingresses []models.Node	netNodes, err := logic.GetNetworkNodes(network)	if err != nil {		return []models.Node{}, err	}	for i := range netNodes {		if netNodes[i].IsIngressGateway {			ingresses = append(ingresses, netNodes[i])		}	}	return ingresses, nil}// GetAllowedIpForInetNodeClient - get inet cidr for node using a inet gwfunc 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}
 |