diff --git a/controllers/acls.go b/controllers/acls.go index ef56b3a0..5420c84f 100644 --- a/controllers/acls.go +++ b/controllers/acls.go @@ -181,12 +181,10 @@ func aclDebug(w http.ResponseWriter, r *http.Request) { allowed, ps := logic.IsNodeAllowedToCommunicate(node, peer, true) isallowed := logic.IsPeerAllowed(node, peer, true) - acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network)) re := resp{ IsNodeAllowed: allowed, IsPeerAllowed: isallowed, Policies: ps, - EgressNets: logic.GetNetworkEgressInfo(models.NetworkID(node.Network), acls), } if peerIsStatic == "true" { ingress, err := logic.GetNodeByID(peer.StaticNode.IngressGatewayID) diff --git a/controllers/egress.go b/controllers/egress.go index 67809902..04dfa43b 100644 --- a/controllers/egress.go +++ b/controllers/egress.go @@ -62,7 +62,6 @@ func createEgress(w http.ResponseWriter, r *http.Request) { Description: req.Description, Range: egressRange, Nat: req.Nat, - IsInetGw: req.IsInetGw, Nodes: make(datatypes.JSONMap), Tags: make(datatypes.JSONMap), Status: true, @@ -85,23 +84,6 @@ func createEgress(w http.ResponseWriter, r *http.Request) { ) return } - if e.IsInetGw { - for nodeID := range req.Nodes { - node, err := logic.GetNodeByID(nodeID) - if err == nil && !node.IsGw { - node.IsGw = true - node.IsIngressGateway = true - node.IsRelay = true - if node.Address.IP != nil { - node.IngressDNS = node.Address.IP.String() - } else { - node.IngressDNS = node.Address6.IP.String() - } - - logic.UpsertNode(&node) - } - } - } logic.LogEvent(&models.Event{ Action: models.Create, Source: models.Subject{ @@ -196,14 +178,10 @@ func updateEgress(w http.ResponseWriter, r *http.Request) { return } var updateNat bool - var updateInetGw bool var updateStatus bool if req.Nat != e.Nat { updateNat = true } - if req.IsInetGw != e.IsInetGw { - updateInetGw = true - } if req.Status != e.Status { updateStatus = true } @@ -236,7 +214,6 @@ func updateEgress(w http.ResponseWriter, r *http.Request) { e.Name = req.Name e.Nat = req.Nat e.Status = req.Status - e.IsInetGw = req.IsInetGw e.UpdatedAt = time.Now().UTC() if err := logic.ValidateEgressReq(&e); err != nil { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) @@ -255,10 +232,6 @@ func updateEgress(w http.ResponseWriter, r *http.Request) { e.Nat = req.Nat e.UpdateNatStatus(db.WithContext(context.TODO())) } - if updateInetGw { - e.IsInetGw = req.IsInetGw - e.UpdateINetGwStatus(db.WithContext(context.TODO())) - } if updateStatus { e.Status = req.Status e.UpdateEgressStatus(db.WithContext(context.TODO())) diff --git a/controllers/ext_client.go b/controllers/ext_client.go index 2b640a19..d376d3c8 100644 --- a/controllers/ext_client.go +++ b/controllers/ext_client.go @@ -546,7 +546,7 @@ func getExtClientHAConf(w http.ResponseWriter, r *http.Request) { keepalive = "PersistentKeepalive = " + strconv.Itoa(int(gwnode.IngressPersistentKeepalive)) } var newAllowedIPs string - if logic.IsInternetGw(gwnode) || gwnode.EgressDetails.InternetGwID != "" { + if logic.IsInternetGw(gwnode) || gwnode.InternetGwID != "" { egressrange := "0.0.0.0/0" if gwnode.Address6.IP != nil && client.Address6 != "" { egressrange += "," + "::/0" diff --git a/logic/acls.go b/logic/acls.go index bdb6e417..891fd3f7 100644 --- a/logic/acls.go +++ b/logic/acls.go @@ -608,35 +608,6 @@ func checkIfAclTagisValid(a models.Acl, t models.AclPolicyTag, isSrc bool) (err if err != nil { return errors.New("invalid egress") } - if e.IsInetGw { - req := models.InetNodeReq{} - for _, srcI := range a.Src { - if srcI.ID == models.NodeID { - _, nodeErr := GetNodeByID(srcI.Value) - if nodeErr != nil { - _, staticNodeErr := GetExtClient(srcI.Value, a.NetworkID.String()) - if staticNodeErr != nil { - return errors.New("invalid node " + srcI.Value) - } - } else { - req.InetNodeClientIDs = append(req.InetNodeClientIDs, srcI.Value) - } - - } - } - if len(e.Nodes) > 0 { - for k := range e.Nodes { - inetNode, err := GetNodeByID(k) - if err != nil { - return errors.New("invalid node " + k) - } - if err = ValidateInetGwReq(inetNode, req, false); err != nil { - return err - } - } - } - - } default: return errors.New("invalid policy") } @@ -846,47 +817,6 @@ var GetInetClientsFromAclPolicies = func(eID string) (inetClientIDs []string) { return } -var IsNodeUsingInternetGw = func(node *models.Node, acls []models.Acl) { - host, err := GetHost(node.HostID.String()) - if err != nil { - return - } - if host.IsDefault || node.IsFailOver { - return - } - var isUsing bool - for _, acl := range acls { - if !acl.Enabled { - continue - } - srcVal := ConvAclTagToValueMap(acl.Src) - for _, dstI := range acl.Dst { - if dstI.ID == models.EgressID { - e := schema.Egress{ID: dstI.Value} - err := e.Get(db.WithContext(context.TODO())) - if err != nil || !e.Status { - continue - } - - if e.IsInetGw { - if _, ok := srcVal[node.ID.String()]; ok { - for nodeID := range e.Nodes { - if nodeID == node.ID.String() { - continue - } - node.EgressDetails.InternetGwID = nodeID - isUsing = true - return - } - } - } - } - } - } - if !isUsing { - node.EgressDetails.InternetGwID = "" - } -} var ( CreateDefaultTags = func(netID models.NetworkID) {} diff --git a/logic/egress.go b/logic/egress.go index 949154a9..b92690d9 100644 --- a/logic/egress.go +++ b/logic/egress.go @@ -5,7 +5,6 @@ import ( "encoding/json" "errors" "maps" - "net" "github.com/gravitl/netmaker/db" "github.com/gravitl/netmaker/models" @@ -20,41 +19,12 @@ func ValidateEgressReq(e *schema.Egress) error { if err != nil { return errors.New("failed to get network " + err.Error()) } - if !e.IsInetGw { - if e.Range == "" { - return errors.New("egress range is empty") - } - _, _, err = net.ParseCIDR(e.Range) - if err != nil { - return errors.New("invalid egress range " + err.Error()) - } - err = ValidateEgressRange(e.Network, []string{e.Range}) - if err != nil { - return errors.New("invalid egress range " + err.Error()) - } - } else { - if len(e.Nodes) > 1 { - return errors.New("can only set one internet routing node") - } - acls, _ := ListAclsByNetwork(models.NetworkID(e.Network)) - req := models.InetNodeReq{} - eli, _ := (&schema.Egress{Network: e.Network}).ListByNetwork(db.WithContext(context.TODO())) - for k := range e.Nodes { - inetNode, err := GetNodeByID(k) - if err != nil { - return errors.New("invalid routing node " + err.Error()) - } - // check if node is acting as egress gw already - - GetNodeEgressInfo(&inetNode, eli, acls) - if err := ValidateInetGwReq(inetNode, req, false); err != nil { - return err - } - - } + if len(e.Nodes) > 1 { + return errors.New("can only set one internet routing node") } - if len(e.Nodes) != 0 { + + if len(e.Nodes) > 0 { for k := range e.Nodes { _, err := GetNodeByID(k) if err != nil { @@ -68,29 +38,19 @@ func ValidateEgressReq(e *schema.Egress) error { func DoesNodeHaveAccessToEgress(node *models.Node, e *schema.Egress, acls []models.Acl) bool { nodeTags := maps.Clone(node.Tags) nodeTags[models.TagID(node.ID.String())] = struct{}{} - if !e.IsInetGw { - nodeTags[models.TagID("*")] = struct{}{} - } - - if !e.IsInetGw { - defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy) - if defaultDevicePolicy.Enabled { - return true - } - } for _, acl := range acls { if !acl.Enabled { continue } srcVal := ConvAclTagToValueMap(acl.Src) - if !e.IsInetGw && acl.AllowedDirection == models.TrafficDirectionBi { + if acl.AllowedDirection == models.TrafficDirectionBi { if _, ok := srcVal["*"]; ok { return true } } for _, dstI := range acl.Dst { - if !e.IsInetGw && dstI.ID == models.NodeTagID && dstI.Value == "*" { + if dstI.ID == models.NodeTagID && dstI.Value == "*" { return true } if dstI.ID == models.EgressID && dstI.Value == e.ID { @@ -127,21 +87,11 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node, eli []schema.Egr NodeID: targetNode.ID.String(), NetID: targetNode.Network, } - defer func() { - if targetNode.Mutex != nil { - targetNode.Mutex.Lock() - } - IsNodeUsingInternetGw(targetNode, acls) - if targetNode.Mutex != nil { - targetNode.Mutex.Unlock() - } - }() - for _, e := range eli { if !e.Status || e.Network != targetNode.Network { continue } - if !isDefaultPolicyActive || e.IsInetGw { + if !isDefaultPolicyActive { if !DoesNodeHaveAccessToEgress(node, &e, acls) { if node.IsRelayed && node.RelayedBy == targetNode.ID.String() { if !DoesNodeHaveAccessToEgress(targetNode, &e, acls) { @@ -155,37 +105,17 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node, eli []schema.Egr } if metric, ok := e.Nodes[targetNode.ID.String()]; ok { - if e.IsInetGw { - targetNode.EgressDetails.IsInternetGateway = true - targetNode.EgressDetails.InetNodeReq = models.InetNodeReq{ - InetNodeClientIDs: GetInetClientsFromAclPolicies(e.ID), - } - req.Ranges = append(req.Ranges, "0.0.0.0/0") - req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ - Network: "0.0.0.0/0", - Nat: true, - RouteMetric: 256, - }) - req.Ranges = append(req.Ranges, "::/0") - req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ - Network: "::/0", - Nat: true, - RouteMetric: 256, - }) - } else { - m64, err := metric.(json.Number).Int64() - if err != nil { - m64 = 256 - } - m := uint32(m64) - req.Ranges = append(req.Ranges, e.Range) - req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ - Network: e.Range, - Nat: e.Nat, - RouteMetric: m, - }) + m64, err := metric.(json.Number).Int64() + if err != nil { + m64 = 256 } - + m := uint32(m64) + req.Ranges = append(req.Ranges, e.Range) + req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ + Network: e.Range, + Nat: e.Nat, + RouteMetric: m, + }) } } if targetNode.Mutex != nil { @@ -205,132 +135,28 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node, eli []schema.Egr } } -// TODO -func GetNetworkEgressInfo(network models.NetworkID, acls []models.Acl) (egressNodes map[string]models.Node) { - eli, _ := (&schema.Egress{Network: network.String()}).ListByNetwork(db.WithContext(context.TODO())) - egressNodes = make(map[string]models.Node) - var err error - for _, e := range eli { - if !e.Status || e.Nodes == nil { - continue - } - - for nodeID, metric := range e.Nodes { - - targetNode, ok := egressNodes[nodeID] - if !ok { - targetNode, err = GetNodeByID(nodeID) - if err != nil { - continue - } - } - req := models.EgressGatewayRequest{ - NodeID: targetNode.ID.String(), - NetID: targetNode.Network, - } - IsNodeUsingInternetGw(&targetNode, acls) - if e.IsInetGw { - targetNode.EgressDetails.IsInternetGateway = true - targetNode.EgressDetails.InetNodeReq = models.InetNodeReq{ - InetNodeClientIDs: GetInetClientsFromAclPolicies(e.ID), - } - req.Ranges = append(req.Ranges, "0.0.0.0/0") - req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ - Network: "0.0.0.0/0", - Nat: true, - RouteMetric: 256, - }) - req.Ranges = append(req.Ranges, "::/0") - req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ - Network: "::/0", - Nat: true, - RouteMetric: 256, - }) - } else { - m64, err := metric.(json.Number).Int64() - if err != nil { - m64 = 256 - } - m := uint32(m64) - req.Ranges = append(req.Ranges, e.Range) - req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ - Network: e.Range, - Nat: e.Nat, - RouteMetric: m, - }) - } - if targetNode.Mutex != nil { - targetNode.Mutex.Lock() - } - if len(req.Ranges) > 0 { - targetNode.EgressDetails.IsEgressGateway = true - targetNode.EgressDetails.EgressGatewayRanges = append(targetNode.EgressDetails.EgressGatewayRanges, req.Ranges...) - targetNode.EgressDetails.EgressGatewayRequest.Ranges = append(targetNode.EgressDetails.EgressGatewayRequest.Ranges, req.Ranges...) - targetNode.EgressDetails.EgressGatewayRequest.RangesWithMetric = append(targetNode.EgressDetails.EgressGatewayRequest.RangesWithMetric, - req.RangesWithMetric...) - targetNode.EgressDetails.EgressGatewayRequest = req - egressNodes[targetNode.ID.String()] = targetNode - } - if targetNode.Mutex != nil { - targetNode.Mutex.Unlock() - } - - } - - } - return -} - func GetNodeEgressInfo(targetNode *models.Node, eli []schema.Egress, acls []models.Acl) { req := models.EgressGatewayRequest{ NodeID: targetNode.ID.String(), NetID: targetNode.Network, } - defer func() { - if targetNode.Mutex != nil { - targetNode.Mutex.Lock() - } - IsNodeUsingInternetGw(targetNode, acls) - if targetNode.Mutex != nil { - targetNode.Mutex.Unlock() - } - }() for _, e := range eli { if !e.Status || e.Network != targetNode.Network { continue } if metric, ok := e.Nodes[targetNode.ID.String()]; ok { - if e.IsInetGw { - targetNode.EgressDetails.IsInternetGateway = true - targetNode.EgressDetails.InetNodeReq = models.InetNodeReq{ - InetNodeClientIDs: GetInetClientsFromAclPolicies(e.ID), - } - req.Ranges = append(req.Ranges, "0.0.0.0/0") - req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ - Network: "0.0.0.0/0", - Nat: true, - RouteMetric: 256, - }) - req.Ranges = append(req.Ranges, "::/0") - req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ - Network: "::/0", - Nat: true, - RouteMetric: 256, - }) - } else { - m64, err := metric.(json.Number).Int64() - if err != nil { - m64 = 256 - } - m := uint32(m64) - req.Ranges = append(req.Ranges, e.Range) - req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ - Network: e.Range, - Nat: e.Nat, - RouteMetric: m, - }) + m64, err := metric.(json.Number).Int64() + if err != nil { + m64 = 256 } + m := uint32(m64) + req.Ranges = append(req.Ranges, e.Range) + req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{ + Network: e.Range, + Nat: e.Nat, + RouteMetric: m, + }) } } diff --git a/logic/extpeers.go b/logic/extpeers.go index 7a892c28..2c0d97f8 100644 --- a/logic/extpeers.go +++ b/logic/extpeers.go @@ -84,17 +84,7 @@ func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) { GetNodeEgressInfo(¤tNode, eli, acls) if currentNode.EgressDetails.IsEgressGateway { // add the egress gateway range(s) to the result if len(currentNode.EgressDetails.EgressGatewayRanges) > 0 { - if currentNode.EgressDetails.IsInternetGateway && client.IngressGatewayID != currentNode.ID.String() { - for _, rangeI := range currentNode.EgressDetails.EgressGatewayRanges { - if rangeI == "0.0.0.0/0" || rangeI == "::/0" { - continue - } else { - result = append(result, rangeI) - } - } - } else { - result = append(result, currentNode.EgressDetails.EgressGatewayRanges...) - } + result = append(result, currentNode.EgressDetails.EgressGatewayRanges...) } } } diff --git a/logic/gateway.go b/logic/gateway.go index a8c96e9a..1851035f 100644 --- a/logic/gateway.go +++ b/logic/gateway.go @@ -1,7 +1,6 @@ package logic import ( - "context" "errors" "fmt" "slices" @@ -9,27 +8,14 @@ import ( "time" "github.com/gravitl/netmaker/database" - "github.com/gravitl/netmaker/db" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" - "github.com/gravitl/netmaker/schema" "github.com/gravitl/netmaker/servercfg" ) // IsInternetGw - checks if node is acting as internet gw func IsInternetGw(node models.Node) bool { - e := schema.Egress{ - Network: node.Network, - } - egList, _ := e.ListByNetwork(db.WithContext(context.TODO())) - for _, egI := range egList { - if egI.IsInetGw { - if _, ok := egI.Nodes[node.ID.String()]; ok { - return true - } - } - } - return false + return node.IsInternetGateway } // GetInternetGateways - gets all the nodes that are internet gateways @@ -40,7 +26,7 @@ func GetInternetGateways() ([]models.Node, error) { } igs := make([]models.Node, 0) for _, node := range nodes { - if node.EgressDetails.IsInternetGateway { + if node.IsInternetGateway { igs = append(igs, node) } } @@ -205,12 +191,12 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq node.IsIngressGateway = true node.IsGw = true if !servercfg.IsPro { - node.EgressDetails.IsInternetGateway = ingress.IsInternetGateway + node.IsInternetGateway = ingress.IsInternetGateway } node.IngressGatewayRange = network.AddressRange node.IngressGatewayRange6 = network.AddressRange6 node.IngressDNS = ingress.ExtclientDNS - if node.EgressDetails.IsInternetGateway && node.IngressDNS == "" { + if node.IsInternetGateway && node.IngressDNS == "" { node.IngressDNS = "1.1.1.1" } node.IngressPersistentKeepalive = 20 @@ -284,7 +270,7 @@ func DeleteIngressGateway(nodeid string) (models.Node, []models.ExtClient, error node.LastModified = time.Now().UTC() node.IsIngressGateway = false if !servercfg.IsPro { - node.EgressDetails.IsInternetGateway = false + node.IsInternetGateway = false } delete(node.Tags, models.TagID(fmt.Sprintf("%s.%s", node.Network, models.GwTagName))) node.IngressGatewayRange = "" diff --git a/logic/nodes.go b/logic/nodes.go index 92fc8751..a949e872 100644 --- a/logic/nodes.go +++ b/logic/nodes.go @@ -30,8 +30,6 @@ var ( nodeNetworkCacheMutex = &sync.RWMutex{} nodesCacheMap = make(map[string]models.Node) nodesNetworkCacheMap = make(map[string]map[string]models.Node) - IPv4Network = "0.0.0.0/0" - IPv6Network = "::/0" ) func getNodeFromCache(nodeID string) (node models.Node, ok bool) { @@ -283,21 +281,21 @@ func DeleteNode(node *models.Node, purge bool) error { // unset all the relayed nodes SetRelayedNodes(false, node.ID.String(), node.RelayedNodes) } - if node.EgressDetails.InternetGwID != "" { - inetNode, err := GetNodeByID(node.EgressDetails.InternetGwID) + if node.InternetGwID != "" { + inetNode, err := GetNodeByID(node.InternetGwID) if err == nil { clientNodeIDs := []string{} - for _, inetNodeClientID := range inetNode.EgressDetails.InetNodeReq.InetNodeClientIDs { + for _, inetNodeClientID := range inetNode.InetNodeReq.InetNodeClientIDs { if inetNodeClientID == node.ID.String() { continue } clientNodeIDs = append(clientNodeIDs, inetNodeClientID) } - inetNode.EgressDetails.InetNodeReq.InetNodeClientIDs = clientNodeIDs + inetNode.InetNodeReq.InetNodeClientIDs = clientNodeIDs UpsertNode(&inetNode) } } - if node.EgressDetails.IsInternetGateway { + if node.IsInternetGateway { UnsetInternetGw(node) } if !purge && !alreadyDeleted { @@ -826,157 +824,3 @@ func GetAllFailOvers() ([]models.Node, error) { } return igs, nil } - -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.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 := 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.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 := 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 bool -func SetInternetGw(node *models.Node, req models.InetNodeReq) { - node.EgressDetails.IsInternetGateway = true - node.EgressDetails.InetNodeReq = req - for _, clientNodeID := range req.InetNodeClientIDs { - clientNode, err := GetNodeByID(clientNodeID) - if err != nil { - continue - } - clientNode.EgressDetails.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.EgressDetails.InternetGwID { - clientNode.EgressDetails.InternetGwID = "" - 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 := 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 := GetNodeByID(node.EgressDetails.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 -} diff --git a/logic/peers.go b/logic/peers.go index 4b0419d2..1f9d7238 100644 --- a/logic/peers.go +++ b/logic/peers.go @@ -42,6 +42,25 @@ var ( CreateFailOver = func(node models.Node) error { return nil } + // SetDefaulGw + SetDefaultGw = func(node models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate { + return peerUpdate + } + SetDefaultGwForRelayedUpdate = func(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate { + return peerUpdate + } + // UnsetInternetGw + UnsetInternetGw = func(node *models.Node) { + node.IsInternetGateway = false + } + // SetInternetGw + SetInternetGw = func(node *models.Node, req models.InetNodeReq) { + node.IsInternetGateway = true + } + // GetAllowedIpForInetNodeClient + GetAllowedIpForInetNodeClient = func(node, peer *models.Node) []net.IPNet { + return []net.IPNet{} + } ) // GetHostPeerInfo - fetches required peer info per network @@ -468,6 +487,14 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N if node.Address6.IP != nil { egressrange = append(egressrange, "::/0") } + rangeWithMetric := []models.EgressRangeMetric{} + for _, rangeI := range egressrange { + rangeWithMetric = append(rangeWithMetric, models.EgressRangeMetric{ + Network: rangeI, + RouteMetric: 256, + Nat: true, + }) + } hostPeerUpdate.FwUpdate.EgressInfo[fmt.Sprintf("%s-%s", node.ID.String(), "inet")] = models.EgressInfo{ EgressID: fmt.Sprintf("%s-%s", node.ID.String(), "inet"), Network: node.PrimaryAddressIPNet(), @@ -481,10 +508,11 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N Mask: getCIDRMaskFromAddr(node.Address6.IP.String()), }, EgressGWCfg: models.EgressGatewayRequest{ - NodeID: fmt.Sprintf("%s-%s", node.ID.String(), "inet"), - NetID: node.Network, - NatEnabled: "yes", - Ranges: egressrange, + NodeID: fmt.Sprintf("%s-%s", node.ID.String(), "inet"), + NetID: node.Network, + NatEnabled: "yes", + Ranges: egressrange, + RangesWithMetric: rangeWithMetric, }, } } @@ -583,15 +611,15 @@ func filterConflictingEgressRoutesWithMetric(node, peer models.Node) []models.Eg func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet { var allowedips []net.IPNet allowedips = getNodeAllowedIPs(peer, node) - if peer.EgressDetails.IsInternetGateway && node.EgressDetails.InternetGwID == peer.ID.String() { + if peer.IsInternetGateway && node.InternetGwID == peer.ID.String() { allowedips = append(allowedips, GetAllowedIpForInetNodeClient(node, peer)...) return allowedips } if node.IsRelayed && node.RelayedBy == peer.ID.String() { allowedips = append(allowedips, GetAllowedIpsForRelayed(node, peer)...) - // if peer.EgressDetails.InternetGwID != "" { - // return allowedips - // } + if peer.InternetGwID != "" { + return allowedips + } } // handle ingress gateway peers diff --git a/logic/relay.go b/logic/relay.go index f3be7b80..0150925d 100644 --- a/logic/relay.go +++ b/logic/relay.go @@ -123,10 +123,10 @@ func ValidateRelay(relay models.RelayRequest, update bool) error { if relayedNode.IsIngressGateway { return errors.New("cannot relay an ingress gateway (" + relayedNodeID + ")") } - if relayedNode.EgressDetails.IsInternetGateway { + if relayedNode.IsInternetGateway { return errors.New("cannot relay an internet gateway (" + relayedNodeID + ")") } - if relayedNode.EgressDetails.InternetGwID != "" && relayedNode.EgressDetails.InternetGwID != relay.NodeID { + if relayedNode.InternetGwID != "" && relayedNode.InternetGwID != relay.NodeID { return errors.New("cannot relay an internet client (" + relayedNodeID + ")") } if relayedNode.IsFailOver { @@ -217,9 +217,9 @@ func GetAllowedIpsForRelayed(relayed, relay *models.Node) (allowedIPs []net.IPNe logger.Log(0, "RelayedByRelay called with invalid parameters") return } - // if relay.EgressDetails.InternetGwID != "" { - // return GetAllowedIpForInetNodeClient(relayed, relay) - // } + if relay.InternetGwID != "" { + return GetAllowedIpForInetNodeClient(relayed, relay) + } peers, err := GetNetworkNodes(relay.Network) if err != nil { logger.Log(0, "error getting network clients", err.Error()) diff --git a/migrate/migrate.go b/migrate/migrate.go index 69973e1f..92b93e8d 100644 --- a/migrate/migrate.go +++ b/migrate/migrate.go @@ -570,105 +570,6 @@ func migrateToEgressV1() { logic.UpsertNode(&node) } - - if node.IsInternetGateway { - inetHost, err := logic.GetHost(node.HostID.String()) - if err != nil { - continue - } - e := schema.Egress{ - ID: uuid.New().String(), - Name: fmt.Sprintf("%s inet gw", inetHost.Name), - Description: "add description", - Network: node.Network, - Nodes: datatypes.JSONMap{ - node.ID.String(): 256, - }, - Tags: make(datatypes.JSONMap), - Range: "*", - IsInetGw: true, - Nat: true, - Status: true, - CreatedBy: user.UserName, - CreatedAt: time.Now().UTC(), - } - err = e.Create(db.WithContext(context.TODO())) - if err == nil { - node.IsEgressGateway = false - node.EgressGatewayRequest = models.EgressGatewayRequest{} - node.EgressGatewayNatEnabled = false - node.EgressGatewayRanges = []string{} - node.IsInternetGateway = false - src := []models.AclPolicyTag{} - for _, inetClientID := range node.InetNodeReq.InetNodeClientIDs { - _, err := logic.GetNodeByID(inetClientID) - if err == nil { - src = append(src, models.AclPolicyTag{ - ID: models.NodeID, - Value: inetClientID, - }) - } - } - acl := models.Acl{ - ID: uuid.New().String(), - Name: "exit node policy", - MetaData: "all traffic on source nodes will pass through the destination node in the policy", - Default: false, - ServiceType: models.Any, - NetworkID: models.NetworkID(node.Network), - Proto: models.ALL, - RuleType: models.DevicePolicy, - Src: src, - Dst: []models.AclPolicyTag{ - { - ID: models.EgressID, - Value: e.ID, - }, - }, - - AllowedDirection: models.TrafficDirectionBi, - Enabled: true, - CreatedBy: "auto", - CreatedAt: time.Now().UTC(), - } - logic.InsertAcl(acl) - - acl = models.Acl{ - ID: uuid.New().String(), - Name: "exit node policy", - MetaData: "all traffic will pass through the destination node in the policy", - Default: false, - ServiceType: models.Any, - NetworkID: models.NetworkID(node.Network), - Proto: models.ALL, - RuleType: models.UserPolicy, - Src: []models.AclPolicyTag{ - { - ID: models.UserAclID, - Value: "*", - }, - }, - Dst: []models.AclPolicyTag{ - { - ID: models.EgressID, - Value: e.ID, - }, - }, - - AllowedDirection: models.TrafficDirectionBi, - Enabled: true, - CreatedBy: "auto", - CreatedAt: time.Now().UTC(), - } - logic.InsertAcl(acl) - node.InetNodeReq = models.InetNodeReq{} - logic.UpsertNode(&node) - } - } - if node.InternetGwID != "" { - node.InternetGwID = "" - logic.UpsertNode(&node) - } } } diff --git a/models/api_node.go b/models/api_node.go index 5d857f67..1ca51a23 100644 --- a/models/api_node.go +++ b/models/api_node.go @@ -86,9 +86,9 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node { convertedNode.IngressDNS = a.IngressDns convertedNode.IngressPersistentKeepalive = a.IngressPersistentKeepalive convertedNode.IngressMTU = a.IngressMTU - convertedNode.EgressDetails.IsInternetGateway = a.IsInternetGateway - convertedNode.EgressDetails.InternetGwID = currentNode.EgressDetails.InternetGwID - convertedNode.EgressDetails.InetNodeReq = currentNode.EgressDetails.InetNodeReq + convertedNode.IsInternetGateway = a.IsInternetGateway + convertedNode.InternetGwID = currentNode.InternetGwID + convertedNode.InetNodeReq = currentNode.InetNodeReq convertedNode.RelayedNodes = a.RelayedNodes convertedNode.DefaultACL = a.DefaultACL convertedNode.OwnerID = currentNode.OwnerID @@ -196,9 +196,9 @@ func (nm *Node) ConvertToAPINode() *ApiNode { apiNode.Connected = nm.Connected apiNode.PendingDelete = nm.PendingDelete apiNode.DefaultACL = nm.DefaultACL - apiNode.IsInternetGateway = nm.EgressDetails.IsInternetGateway - apiNode.InternetGwID = nm.EgressDetails.InternetGwID - apiNode.InetNodeReq = nm.EgressDetails.InetNodeReq + apiNode.IsInternetGateway = nm.IsInternetGateway + apiNode.InternetGwID = nm.InternetGwID + apiNode.InetNodeReq = nm.InetNodeReq apiNode.IsFailOver = nm.IsFailOver apiNode.FailOverPeers = nm.FailOverPeers apiNode.FailedOverBy = nm.FailedOverBy diff --git a/models/node.go b/models/node.go index e98b8131..33aefb19 100644 --- a/models/node.go +++ b/models/node.go @@ -127,9 +127,9 @@ type EgressDetails struct { EgressGatewayRequest EgressGatewayRequest IsEgressGateway bool EgressGatewayRanges []string - IsInternetGateway bool `json:"isinternetgateway" yaml:"isinternetgateway"` - InetNodeReq InetNodeReq `json:"inet_node_req" yaml:"inet_node_req"` - InternetGwID string `json:"internetgw_node_id" yaml:"internetgw_node_id"` + // IsInternetGateway bool `json:"isinternetgateway" yaml:"isinternetgateway"` + // InetNodeReq InetNodeReq `json:"inet_node_req" yaml:"inet_node_req"` + // InternetGwID string `json:"internetgw_node_id" yaml:"internetgw_node_id"` } // LegacyNode - legacy struct for node model diff --git a/pro/controllers/failover.go b/pro/controllers/failover.go index 5957494c..2321ad62 100644 --- a/pro/controllers/failover.go +++ b/pro/controllers/failover.go @@ -253,8 +253,8 @@ func failOverME(w http.ResponseWriter, r *http.Request) { ) return } - if (node.EgressDetails.InternetGwID != "" && failOverNode.EgressDetails.IsInternetGateway && node.EgressDetails.InternetGwID != failOverNode.ID.String()) || - (peerNode.EgressDetails.InternetGwID != "" && failOverNode.EgressDetails.IsInternetGateway && peerNode.EgressDetails.InternetGwID != failOverNode.ID.String()) { + if (node.InternetGwID != "" && failOverNode.IsInternetGateway && node.InternetGwID != failOverNode.ID.String()) || + (peerNode.InternetGwID != "" && failOverNode.IsInternetGateway && peerNode.InternetGwID != failOverNode.ID.String()) { logic.ReturnErrorResponse( w, r, @@ -265,7 +265,7 @@ func failOverME(w http.ResponseWriter, r *http.Request) { ) return } - if node.EgressDetails.IsInternetGateway && peerNode.EgressDetails.InternetGwID == node.ID.String() { + if node.IsInternetGateway && peerNode.InternetGwID == node.ID.String() { logic.ReturnErrorResponse( w, r, @@ -276,7 +276,7 @@ func failOverME(w http.ResponseWriter, r *http.Request) { ) return } - if node.EgressDetails.InternetGwID != "" && node.EgressDetails.InternetGwID == peerNode.ID.String() { + if node.InternetGwID != "" && node.InternetGwID == peerNode.ID.String() { logic.ReturnErrorResponse( w, r, @@ -414,8 +414,8 @@ func checkfailOverCtx(w http.ResponseWriter, r *http.Request) { ) return } - if (node.EgressDetails.InternetGwID != "" && failOverNode.EgressDetails.IsInternetGateway && node.EgressDetails.InternetGwID != failOverNode.ID.String()) || - (peerNode.EgressDetails.InternetGwID != "" && failOverNode.EgressDetails.IsInternetGateway && peerNode.EgressDetails.InternetGwID != failOverNode.ID.String()) { + if (node.InternetGwID != "" && failOverNode.IsInternetGateway && node.InternetGwID != failOverNode.ID.String()) || + (peerNode.InternetGwID != "" && failOverNode.IsInternetGateway && peerNode.InternetGwID != failOverNode.ID.String()) { logic.ReturnErrorResponse( w, r, @@ -426,7 +426,7 @@ func checkfailOverCtx(w http.ResponseWriter, r *http.Request) { ) return } - if node.EgressDetails.IsInternetGateway && peerNode.EgressDetails.InternetGwID == node.ID.String() { + if node.IsInternetGateway && peerNode.InternetGwID == node.ID.String() { logic.ReturnErrorResponse( w, r, @@ -437,7 +437,7 @@ func checkfailOverCtx(w http.ResponseWriter, r *http.Request) { ) return } - if node.EgressDetails.InternetGwID != "" && node.EgressDetails.InternetGwID == peerNode.ID.String() { + if node.InternetGwID != "" && node.InternetGwID == peerNode.ID.String() { logic.ReturnErrorResponse( w, r, diff --git a/pro/controllers/inet_gws.go b/pro/controllers/inet_gws.go index c1fb3787..4a286580 100644 --- a/pro/controllers/inet_gws.go +++ b/pro/controllers/inet_gws.go @@ -44,7 +44,7 @@ func createInternetGw(w http.ResponseWriter, r *http.Request) { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) return } - if node.EgressDetails.IsInternetGateway { + if node.IsInternetGateway { logic.ReturnSuccessResponse(w, r, "node is already acting as internet gateway") return } @@ -70,7 +70,7 @@ func createInternetGw(w http.ResponseWriter, r *http.Request) { ) return } - err = logic.ValidateInetGwReq(node, request, false) + err = proLogic.ValidateInetGwReq(node, request, false) if err != nil { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) return @@ -132,7 +132,7 @@ func updateInternetGw(w http.ResponseWriter, r *http.Request) { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) return } - if !node.EgressDetails.IsInternetGateway { + if !node.IsInternetGateway { logic.ReturnErrorResponse( w, r, @@ -140,7 +140,7 @@ func updateInternetGw(w http.ResponseWriter, r *http.Request) { ) return } - err = logic.ValidateInetGwReq(node, request, true) + err = proLogic.ValidateInetGwReq(node, request, true) if err != nil { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) return diff --git a/pro/controllers/users.go b/pro/controllers/users.go index 79cbc49a..d8722d8b 100644 --- a/pro/controllers/users.go +++ b/pro/controllers/users.go @@ -1092,7 +1092,7 @@ func getUserRemoteAccessNetworkGateways(w http.ResponseWriter, r *http.Request) GwID: node.ID.String(), GWName: host.Name, Network: node.Network, - IsInternetGateway: node.EgressDetails.IsInternetGateway, + IsInternetGateway: node.IsInternetGateway, Metadata: node.Metadata, }) @@ -1219,7 +1219,7 @@ func getRemoteAccessGatewayConf(w http.ResponseWriter, r *http.Request) { Network: node.Network, GwClient: userConf, Connected: true, - IsInternetGateway: node.EgressDetails.IsInternetGateway, + IsInternetGateway: node.IsInternetGateway, GwPeerPublicKey: host.PublicKey.String(), GwListenPort: logic.GetPeerListenPort(host), Metadata: node.Metadata, @@ -1311,7 +1311,7 @@ func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) { Network: node.Network, GwClient: extClient, Connected: true, - IsInternetGateway: node.EgressDetails.IsInternetGateway, + IsInternetGateway: node.IsInternetGateway, GwPeerPublicKey: host.PublicKey.String(), GwListenPort: logic.GetPeerListenPort(host), Metadata: node.Metadata, @@ -1355,7 +1355,7 @@ func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) { GwID: node.ID.String(), GWName: host.Name, Network: node.Network, - IsInternetGateway: node.EgressDetails.IsInternetGateway, + IsInternetGateway: node.IsInternetGateway, GwPeerPublicKey: host.PublicKey.String(), GwListenPort: logic.GetPeerListenPort(host), Metadata: node.Metadata, diff --git a/pro/initialize.go b/pro/initialize.go index 91e29eda..5f581fd1 100644 --- a/pro/initialize.go +++ b/pro/initialize.go @@ -113,6 +113,11 @@ func InitPro() { logic.UpdateMetrics = proLogic.UpdateMetrics logic.DeleteMetrics = proLogic.DeleteMetrics logic.GetTrialEndDate = getTrialEndDate + logic.SetDefaultGw = proLogic.SetDefaultGw + logic.SetDefaultGwForRelayedUpdate = proLogic.SetDefaultGwForRelayedUpdate + logic.UnsetInternetGw = proLogic.UnsetInternetGw + logic.SetInternetGw = proLogic.SetInternetGw + logic.GetAllowedIpForInetNodeClient = proLogic.GetAllowedIpForInetNodeClient mq.UpdateMetrics = proLogic.MQUpdateMetrics mq.UpdateMetricsFallBack = proLogic.MQUpdateMetricsFallBack logic.GetFilteredNodesByUserAccess = proLogic.GetFilteredNodesByUserAccess @@ -145,7 +150,6 @@ func InitPro() { logic.IsUserAllowedToCommunicate = proLogic.IsUserAllowedToCommunicate logic.DeleteAllNetworkTags = proLogic.DeleteAllNetworkTags logic.CreateDefaultTags = proLogic.CreateDefaultTags - logic.IsNodeUsingInternetGw = proLogic.IsNodeUsingInternetGw logic.GetInetClientsFromAclPolicies = proLogic.GetInetClientsFromAclPolicies logic.IsPeerAllowed = proLogic.IsPeerAllowed logic.IsAclPolicyValid = proLogic.IsAclPolicyValid diff --git a/pro/logic/acls.go b/pro/logic/acls.go index 621085bb..231764e1 100644 --- a/pro/logic/acls.go +++ b/pro/logic/acls.go @@ -6,24 +6,12 @@ import ( "maps" "net" - "github.com/google/uuid" "github.com/gravitl/netmaker/db" "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/models" "github.com/gravitl/netmaker/schema" ) -/* -TODO: EGRESS -1. allow only selection of egress ranges in a policy -ranges should be replaced by egress identifier - -2. check logic required for MAC exit node - -3. - -*/ - func GetFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []models.FwRule) { defaultUserPolicy, _ := logic.GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy) userNodes := logic.GetStaticUserNodesByNetwork(models.NetworkID(node.Network)) @@ -313,43 +301,6 @@ func checkIfAclTagisValid(a models.Acl, t models.AclPolicyTag, isSrc bool) (err if err != nil { return errors.New("invalid egress") } - if e.IsInetGw { - req := models.InetNodeReq{} - for _, srcI := range a.Src { - if srcI.ID == models.NodeTagID { - nodesMap := GetNodesWithTag(models.TagID(srcI.Value)) - for _, node := range nodesMap { - if node.ID != uuid.Nil { - req.InetNodeClientIDs = append(req.InetNodeClientIDs, node.ID.String()) - } - } - } else if srcI.ID == models.NodeID { - _, nodeErr := logic.GetNodeByID(srcI.Value) - if nodeErr != nil { - _, staticNodeErr := logic.GetExtClient(srcI.Value, a.NetworkID.String()) - if staticNodeErr != nil { - return errors.New("invalid node " + srcI.Value) - } - } else { - req.InetNodeClientIDs = append(req.InetNodeClientIDs, srcI.Value) - } - - } - } - if len(e.Nodes) > 0 { - for k := range e.Nodes { - inetNode, err := logic.GetNodeByID(k) - if err != nil { - return errors.New("invalid node " + t.Value) - } - if err = logic.ValidateInetGwReq(inetNode, req, false); err != nil { - return err - } - } - - } - - } case models.UserAclID: if a.RuleType == models.DevicePolicy { @@ -966,8 +917,18 @@ func getEgressUserRulesForNode(targetnode *models.Node, acls := listUserPolicies(models.NetworkID(targetnode.Network)) var targetNodeTags = make(map[models.TagID]struct{}) targetNodeTags["*"] = struct{}{} - for _, rangeI := range targetnode.EgressDetails.EgressGatewayRanges { - targetNodeTags[models.TagID(rangeI)] = struct{}{} + egs, _ := (&schema.Egress{Network: targetnode.Network}).ListByNetwork(db.WithContext(context.TODO())) + if len(egs) == 0 { + return rules + } + for _, egI := range egs { + if !egI.Status { + continue + } + if _, ok := egI.Nodes[targetnode.ID.String()]; ok { + targetNodeTags[models.TagID(egI.Range)] = struct{}{} + targetNodeTags[models.TagID(egI.ID)] = struct{}{} + } } for _, acl := range acls { if !acl.Enabled { @@ -1051,26 +1012,15 @@ func getEgressUserRulesForNode(targetnode *models.Node, if err != nil { continue } - if e.IsInetGw { - r.Dst = append(r.Dst, net.IPNet{ - IP: net.IPv4zero, - Mask: net.CIDRMask(0, 32), - }) - r.Dst6 = append(r.Dst6, net.IPNet{ - IP: net.IPv6zero, - Mask: net.CIDRMask(0, 128), - }) - - } else { - ip, cidr, err := net.ParseCIDR(e.Range) - if err == nil { - if ip.To4() != nil { - r.Dst = append(r.Dst, *cidr) - } else { - r.Dst6 = append(r.Dst6, *cidr) - } + ip, cidr, err := net.ParseCIDR(e.Range) + if err == nil { + if ip.To4() != nil { + r.Dst = append(r.Dst, *cidr) + } else { + r.Dst6 = append(r.Dst6, *cidr) } + } } @@ -1530,12 +1480,7 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR continue } if _, ok := egI.Nodes[targetnode.ID.String()]; ok { - if egI.IsInetGw { - targetNodeTags[models.TagID("0.0.0.0/0")] = struct{}{} - targetNodeTags[models.TagID("::/0")] = struct{}{} - } else { - targetNodeTags[models.TagID(egI.Range)] = struct{}{} - } + targetNodeTags[models.TagID(egI.Range)] = struct{}{} targetNodeTags[models.TagID(egI.ID)] = struct{}{} } } @@ -1597,6 +1542,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR if err == nil { nodes = append(nodes, node) } + extclient, err := logic.GetExtClient(dst, targetnode.Network) + if err == nil { + nodes = append(nodes, extclient.ConvertToStaticNode()) + } } for _, node := range nodes { @@ -1631,6 +1580,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR if err == nil { nodes = append(nodes, node) } + extclient, err := logic.GetExtClient(src, targetnode.Network) + if err == nil { + nodes = append(nodes, extclient.ConvertToStaticNode()) + } } for _, node := range nodes { if node.ID == targetnode.ID { @@ -1661,6 +1614,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR if err == nil { nodes = append(nodes, node) } + extclient, err := logic.GetExtClient(srcID, targetnode.Network) + if err == nil { + nodes = append(nodes, extclient.ConvertToStaticNode()) + } } for dstID := range dstTags { if dstID == targetnode.ID.String() { @@ -1670,6 +1627,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR if err == nil { nodes = append(nodes, node) } + extclient, err := logic.GetExtClient(dstID, targetnode.Network) + if err == nil { + nodes = append(nodes, extclient.ConvertToStaticNode()) + } } for _, node := range nodes { if node.ID == targetnode.ID { @@ -1768,62 +1729,3 @@ func GetInetClientsFromAclPolicies(eID string) (inetClientIDs []string) { } return } - -func IsNodeUsingInternetGw(node *models.Node, acls []models.Acl) { - host, err := logic.GetHost(node.HostID.String()) - if err != nil { - return - } - if host.IsDefault || node.IsFailOver { - return - } - nodeTags := maps.Clone(node.Tags) - if nodeTags == nil { - nodeTags = make(map[models.TagID]struct{}) - } - nodeTags[models.TagID(node.ID.String())] = struct{}{} - var isUsing bool - for _, acl := range acls { - if !acl.Enabled { - continue - } - srcVal := logic.ConvAclTagToValueMap(acl.Src) - for _, dstI := range acl.Dst { - if dstI.ID == models.EgressID { - e := schema.Egress{ID: dstI.Value} - err := e.Get(db.WithContext(context.TODO())) - if err != nil || !e.Status { - continue - } - - if e.IsInetGw { - if _, ok := srcVal[node.ID.String()]; ok { - for nodeID := range e.Nodes { - if nodeID == node.ID.String() { - continue - } - node.EgressDetails.InternetGwID = nodeID - isUsing = true - return - } - } - for tagID := range nodeTags { - if _, ok := srcVal[tagID.String()]; ok { - for nodeID := range e.Nodes { - if nodeID == node.ID.String() { - continue - } - node.EgressDetails.InternetGwID = nodeID - isUsing = true - return - } - } - } - } - } - } - } - if !isUsing { - node.EgressDetails.InternetGwID = "" - } -} diff --git a/pro/logic/nodes.go b/pro/logic/nodes.go index 14a043f7..7feeea04 100644 --- a/pro/logic/nodes.go +++ b/pro/logic/nodes.go @@ -1,8 +1,19 @@ package logic import ( + "errors" + "fmt" + "net" + + "github.com/google/uuid" "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/models" + "golang.org/x/exp/slog" +) + +var ( + IPv4Network = "0.0.0.0/0" + IPv6Network = "::/0" ) // GetNetworkIngresses - gets the gateways of a network @@ -223,3 +234,157 @@ func GetStaticNodeWithTag(tagID models.TagID) map[string]models.Node { } return nMap } + +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.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.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 := logic.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 := logic.GetNodeByID(clientNodeID) + if err != nil { + continue + } + clientNode.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.InternetGwID { + clientNode.InternetGwID = "" + logic.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 := 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.InternetGwID != "" { + + inetNode, err := logic.GetNodeByID(node.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 +} + +// 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 +} diff --git a/schema/egress.go b/schema/egress.go index f24d3813..d420198a 100644 --- a/schema/egress.go +++ b/schema/egress.go @@ -19,11 +19,11 @@ type Egress struct { Tags datatypes.JSONMap `gorm:"tags" json:"tags"` Range string `gorm:"range" json:"range"` Nat bool `gorm:"nat" json:"nat"` - IsInetGw bool `gorm:"is_inet_gw" json:"is_internet_gateway"` - Status bool `gorm:"status" json:"status"` - CreatedBy string `gorm:"created_by" json:"created_by"` - CreatedAt time.Time `gorm:"created_at" json:"created_at"` - UpdatedAt time.Time `gorm:"updated_at" json:"updated_at"` + //IsInetGw bool `gorm:"is_inet_gw" json:"is_internet_gateway"` + Status bool `gorm:"status" json:"status"` + CreatedBy string `gorm:"created_by" json:"created_by"` + CreatedAt time.Time `gorm:"created_at" json:"created_at"` + UpdatedAt time.Time `gorm:"updated_at" json:"updated_at"` } func (e *Egress) Table() string { @@ -44,12 +44,6 @@ func (e *Egress) UpdateNatStatus(ctx context.Context) error { }).Error } -func (e *Egress) UpdateINetGwStatus(ctx context.Context) error { - return db.FromContext(ctx).Table(e.Table()).Where("id = ?", e.ID).Updates(map[string]any{ - "is_inet_gw": e.IsInetGw, - }).Error -} - func (e *Egress) UpdateEgressStatus(ctx context.Context) error { return db.FromContext(ctx).Table(e.Table()).Where("id = ?", e.ID).Updates(map[string]any{ "status": e.Status,