mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-26 21:01:32 +08:00
NET-1932: sort out acls into CE and PRO (#3460)
* move relevant acl and tag code to CE and Pro pkgs * intialise pro acl funcs * list gateways by user access * check user gw access by policies * filter out user policies on CE * filter out tagged policies on CE * fix ce acl comms * allow gateways tag * allow gateway tag on CE, remove failover and gw check on acl policy * add gw rules func to pro * add inet gw support on CE * add egress acl API * add egress acl API * fix(go): set is_gw when converting api node to server node; * fix(go): set is_gw when converting api node to server node; * fix policy validity checker for inet gws * move dns option to host model * fix node removal from egress policy on delete * add migration logic for ManageDNS * fix dns json field * fix nil error on node tags * add egress info to relayed nodes --------- Co-authored-by: Vishal Dalwadi <dalwadivishal26@gmail.com>
This commit is contained in:
@@ -9,15 +9,19 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gravitl/netmaker/db"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
"github.com/gravitl/netmaker/schema"
|
||||
)
|
||||
|
||||
func aclHandlers(r *mux.Router) {
|
||||
r.HandleFunc("/api/v1/acls", logic.SecurityCheck(true, http.HandlerFunc(getAcls))).
|
||||
Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/v1/acls/egress", logic.SecurityCheck(true, http.HandlerFunc(getEgressAcls))).
|
||||
Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/v1/acls/policy_types", logic.SecurityCheck(true, http.HandlerFunc(aclPolicyTypes))).
|
||||
Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/v1/acls", logic.SecurityCheck(true, http.HandlerFunc(createAcl))).
|
||||
@@ -174,7 +178,7 @@ func aclDebug(w http.ResponseWriter, r *http.Request) {
|
||||
NodeAllPolicy bool
|
||||
}
|
||||
|
||||
allowed, ps := logic.IsNodeAllowedToCommunicateV1(node, peer, true)
|
||||
allowed, ps := logic.IsNodeAllowedToCommunicate(node, peer, true)
|
||||
isallowed := logic.IsPeerAllowed(node, peer, true)
|
||||
re := resp{
|
||||
IsNodeAllowed: allowed,
|
||||
@@ -218,6 +222,35 @@ func getAcls(w http.ResponseWriter, r *http.Request) {
|
||||
logic.ReturnSuccessResponseWithJson(w, r, acls, "fetched all acls in the network "+netID)
|
||||
}
|
||||
|
||||
// @Summary List Egress Acls in a network
|
||||
// @Router /api/v1/acls [get]
|
||||
// @Tags ACL
|
||||
// @Accept json
|
||||
// @Success 200 {array} models.SuccessResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func getEgressAcls(w http.ResponseWriter, r *http.Request) {
|
||||
eID := r.URL.Query().Get("egress_id")
|
||||
if eID == "" {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("egress id param is missing"), "badrequest"))
|
||||
return
|
||||
}
|
||||
e := schema.Egress{ID: eID}
|
||||
// check if network exists
|
||||
err := e.Get(db.WithContext(r.Context()))
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
acls, err := logic.ListEgressAcls(eID)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to get all network acl entries: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
logic.SortAclEntrys(acls[:])
|
||||
logic.ReturnSuccessResponseWithJson(w, r, acls, "fetched acls for egress"+e.Name)
|
||||
}
|
||||
|
||||
// @Summary Create Acl
|
||||
// @Router /api/v1/acls [post]
|
||||
// @Tags ACL
|
||||
|
@@ -3,13 +3,14 @@ package controller
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/gravitl/netmaker/db"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gravitl/netmaker/db"
|
||||
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
@@ -37,7 +38,6 @@ var HttpHandlers = []interface{}{
|
||||
loggerHandlers,
|
||||
hostHandlers,
|
||||
enrollmentKeyHandlers,
|
||||
tagHandlers,
|
||||
aclHandlers,
|
||||
egressHandlers,
|
||||
legacyHandlers,
|
||||
|
@@ -65,7 +65,6 @@ func TestGetNodeDNS(t *testing.T) {
|
||||
ID: uuid.New(),
|
||||
Network: "skynet",
|
||||
Address: *ipnet,
|
||||
DNSOn: true,
|
||||
}
|
||||
createnode := models.Node{
|
||||
CommonNode: tmpCNode,
|
||||
@@ -82,7 +81,6 @@ func TestGetNodeDNS(t *testing.T) {
|
||||
ID: uuid.New(),
|
||||
Network: "skynet",
|
||||
Address: *ipnet,
|
||||
DNSOn: true,
|
||||
}
|
||||
createnode := models.Node{
|
||||
CommonNode: tmpCNode,
|
||||
|
@@ -109,6 +109,8 @@ func createGateway(w http.ResponseWriter, r *http.Request) {
|
||||
},
|
||||
Origin: models.Dashboard,
|
||||
})
|
||||
host.IsStaticPort = true
|
||||
logic.UpsertHost(host)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(apiNode)
|
||||
go func() {
|
||||
|
@@ -207,7 +207,6 @@ func convertLegacyNode(legacy models.LegacyNode, hostID uuid.UUID) models.Node {
|
||||
node.IsRelayed = false
|
||||
node.IsRelay = false
|
||||
node.RelayedNodes = []string{}
|
||||
node.DNSOn = models.ParseBool(legacy.DNSOn)
|
||||
node.LastModified = time.Now().UTC()
|
||||
node.ExpirationDateTime = time.Unix(legacy.ExpirationDateTime, 0)
|
||||
node.EgressGatewayNatEnabled = models.ParseBool(legacy.EgressGatewayNatEnabled)
|
||||
|
@@ -143,7 +143,6 @@ func createNodeWithParams(network, address string) *models.Node {
|
||||
ID: uuid.New(),
|
||||
Network: "skynet",
|
||||
Address: *ipnet,
|
||||
DNSOn: true,
|
||||
}
|
||||
if len(network) > 0 {
|
||||
tmpCNode.Network = network
|
||||
|
2600
logic/acls.go
2600
logic/acls.go
File diff suppressed because it is too large
Load Diff
130
logic/egress.go
130
logic/egress.go
@@ -63,93 +63,6 @@ func ValidateEgressReq(e *schema.Egress) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetInetClientsFromAclPolicies(eID string) (inetClientIDs []string) {
|
||||
e := schema.Egress{ID: eID}
|
||||
err := e.Get(db.WithContext(context.TODO()))
|
||||
if err != nil || !e.Status {
|
||||
return
|
||||
}
|
||||
acls, _ := ListAclsByNetwork(models.NetworkID(e.Network))
|
||||
for _, acl := range acls {
|
||||
for _, dstI := range acl.Dst {
|
||||
if dstI.ID == models.EgressID {
|
||||
if dstI.Value != eID {
|
||||
continue
|
||||
}
|
||||
for _, srcI := range acl.Src {
|
||||
if srcI.Value == "*" {
|
||||
continue
|
||||
}
|
||||
if srcI.ID == models.NodeID {
|
||||
inetClientIDs = append(inetClientIDs, srcI.Value)
|
||||
}
|
||||
if srcI.ID == models.NodeTagID {
|
||||
inetClientIDs = append(inetClientIDs, GetNodeIDsWithTag(models.TagID(srcI.Value))...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func isNodeUsingInternetGw(node *models.Node) {
|
||||
host, err := GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if host.IsDefault || node.IsFailOver {
|
||||
return
|
||||
}
|
||||
nodeTags := maps.Clone(node.Tags)
|
||||
nodeTags[models.TagID(node.ID.String())] = struct{}{}
|
||||
acls, _ := ListAclsByNetwork(models.NetworkID(node.Network))
|
||||
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
|
||||
}
|
||||
}
|
||||
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 = ""
|
||||
}
|
||||
}
|
||||
|
||||
func DoesNodeHaveAccessToEgress(node *models.Node, e *schema.Egress) bool {
|
||||
nodeTags := maps.Clone(node.Tags)
|
||||
nodeTags[models.TagID(node.ID.String())] = struct{}{}
|
||||
@@ -167,7 +80,7 @@ func DoesNodeHaveAccessToEgress(node *models.Node, e *schema.Egress) bool {
|
||||
if !acl.Enabled {
|
||||
continue
|
||||
}
|
||||
srcVal := convAclTagToValueMap(acl.Src)
|
||||
srcVal := ConvAclTagToValueMap(acl.Src)
|
||||
if !e.IsInetGw && acl.AllowedDirection == models.TrafficDirectionBi {
|
||||
if _, ok := srcVal["*"]; ok {
|
||||
return true
|
||||
@@ -216,7 +129,7 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node) {
|
||||
if targetNode.Mutex != nil {
|
||||
targetNode.Mutex.Lock()
|
||||
}
|
||||
isNodeUsingInternetGw(targetNode)
|
||||
IsNodeUsingInternetGw(targetNode)
|
||||
if targetNode.Mutex != nil {
|
||||
targetNode.Mutex.Unlock()
|
||||
}
|
||||
@@ -296,7 +209,7 @@ func GetNodeEgressInfo(targetNode *models.Node) {
|
||||
if targetNode.Mutex != nil {
|
||||
targetNode.Mutex.Lock()
|
||||
}
|
||||
isNodeUsingInternetGw(targetNode)
|
||||
IsNodeUsingInternetGw(targetNode)
|
||||
if targetNode.Mutex != nil {
|
||||
targetNode.Mutex.Unlock()
|
||||
}
|
||||
@@ -355,7 +268,9 @@ func GetNodeEgressInfo(targetNode *models.Node) {
|
||||
}
|
||||
|
||||
func RemoveNodeFromEgress(node models.Node) {
|
||||
egs, _ := (&schema.Egress{}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
egs, _ := (&schema.Egress{
|
||||
Network: node.Network,
|
||||
}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
for _, egI := range egs {
|
||||
if _, ok := egI.Nodes[node.ID.String()]; ok {
|
||||
delete(egI.Nodes, node.ID.String())
|
||||
@@ -364,3 +279,36 @@ func RemoveNodeFromEgress(node models.Node) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func GetEgressRanges(netID models.NetworkID) (map[string][]string, map[string]struct{}, error) {
|
||||
|
||||
resultMap := make(map[string]struct{})
|
||||
nodeEgressMap := make(map[string][]string)
|
||||
networkNodes, err := GetNetworkNodes(netID.String())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for _, currentNode := range networkNodes {
|
||||
if currentNode.Network != netID.String() {
|
||||
continue
|
||||
}
|
||||
if currentNode.EgressDetails.IsEgressGateway { // add the egress gateway range(s) to the result
|
||||
if len(currentNode.EgressDetails.EgressGatewayRanges) > 0 {
|
||||
nodeEgressMap[currentNode.ID.String()] = currentNode.EgressDetails.EgressGatewayRanges
|
||||
for _, egressRangeI := range currentNode.EgressDetails.EgressGatewayRanges {
|
||||
resultMap[egressRangeI] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
extclients, _ := GetNetworkExtClients(netID.String())
|
||||
for _, extclient := range extclients {
|
||||
if len(extclient.ExtraAllowedIPs) > 0 {
|
||||
nodeEgressMap[extclient.ClientID] = extclient.ExtraAllowedIPs
|
||||
for _, extraAllowedIP := range extclient.ExtraAllowedIPs {
|
||||
resultMap[extraAllowedIP] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodeEgressMap, resultMap, nil
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -14,11 +13,9 @@ import (
|
||||
|
||||
"github.com/goombaio/namegenerator"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/db"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic/acls"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/schema"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.org/x/exp/slog"
|
||||
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
|
||||
@@ -84,7 +81,6 @@ func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) {
|
||||
continue
|
||||
}
|
||||
if currentNode.EgressDetails.IsEgressGateway { // add the egress gateway range(s) to the result
|
||||
fmt.Println("EGRESSS EXTCLEINT: ", currentNode.EgressDetails)
|
||||
if len(currentNode.EgressDetails.EgressGatewayRanges) > 0 {
|
||||
result = append(result, currentNode.EgressDetails.EgressGatewayRanges...)
|
||||
}
|
||||
@@ -98,7 +94,30 @@ func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) {
|
||||
result = append(result, extclient.ExtraAllowedIPs...)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return UniqueIPNetStrList(result), nil
|
||||
}
|
||||
|
||||
// UniqueIPNetList deduplicates and sorts a list of CIDR strings.
|
||||
func UniqueIPNetStrList(ipnets []string) []string {
|
||||
uniqueMap := make(map[string]struct{})
|
||||
|
||||
for _, cidr := range ipnets {
|
||||
_, ipnet, err := net.ParseCIDR(cidr)
|
||||
if err != nil {
|
||||
continue // skip invalid CIDR strings
|
||||
}
|
||||
key := ipnet.String() // normalized CIDR
|
||||
uniqueMap[key] = struct{}{}
|
||||
}
|
||||
|
||||
// Convert map keys to slice
|
||||
uniqueList := make([]string, 0, len(uniqueMap))
|
||||
for cidr := range uniqueMap {
|
||||
uniqueList = append(uniqueList, cidr)
|
||||
}
|
||||
|
||||
sort.Strings(uniqueList)
|
||||
return uniqueList
|
||||
}
|
||||
|
||||
// DeleteExtClient - deletes an existing ext client
|
||||
@@ -493,362 +512,6 @@ func ToggleExtClientConnectivity(client *models.ExtClient, enable bool) (models.
|
||||
return newClient, nil
|
||||
}
|
||||
|
||||
// Sort a slice of net.IP addresses
|
||||
func sortIPs(ips []net.IP) {
|
||||
sort.Slice(ips, func(i, j int) bool {
|
||||
ip1, ip2 := ips[i].To16(), ips[j].To16()
|
||||
return string(ip1) < string(ip2) // Compare as byte slices
|
||||
})
|
||||
}
|
||||
|
||||
func GetStaticNodeIps(node models.Node) (ips []net.IP) {
|
||||
defer func() {
|
||||
sortIPs(ips)
|
||||
}()
|
||||
defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
||||
defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
||||
|
||||
extclients := GetStaticNodesByNetwork(models.NetworkID(node.Network), false)
|
||||
for _, extclient := range extclients {
|
||||
if extclient.IsUserNode && defaultUserPolicy.Enabled {
|
||||
continue
|
||||
}
|
||||
if !extclient.IsUserNode && defaultDevicePolicy.Enabled {
|
||||
continue
|
||||
}
|
||||
if extclient.StaticNode.Address != "" {
|
||||
ips = append(ips, extclient.StaticNode.AddressIPNet4().IP)
|
||||
}
|
||||
if extclient.StaticNode.Address6 != "" {
|
||||
ips = append(ips, extclient.StaticNode.AddressIPNet6().IP)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getFwRulesForNodeAndPeerOnGw(node, peer models.Node, allowedPolicies []models.Acl) (rules []models.FwRule) {
|
||||
|
||||
for _, policy := range allowedPolicies {
|
||||
// if static peer dst rule not for ingress node -> skip
|
||||
if node.Address.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
DstIP: net.IPNet{
|
||||
IP: peer.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
AllowedProtocol: policy.Proto,
|
||||
AllowedPorts: policy.Port,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
||||
if node.Address6.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
DstIP: net.IPNet{
|
||||
IP: peer.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
AllowedProtocol: policy.Proto,
|
||||
AllowedPorts: policy.Port,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
if policy.AllowedDirection == models.TrafficDirectionBi {
|
||||
if node.Address.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: peer.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
DstIP: net.IPNet{
|
||||
IP: node.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
AllowedProtocol: policy.Proto,
|
||||
AllowedPorts: policy.Port,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
||||
if node.Address6.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: peer.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
DstIP: net.IPNet{
|
||||
IP: node.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
AllowedProtocol: policy.Proto,
|
||||
AllowedPorts: policy.Port,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
if len(node.StaticNode.ExtraAllowedIPs) > 0 {
|
||||
for _, additionalAllowedIPNet := range node.StaticNode.ExtraAllowedIPs {
|
||||
_, ipNet, err := net.ParseCIDR(additionalAllowedIPNet)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if ipNet.IP.To4() != nil && peer.Address.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: peer.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
DstIP: *ipNet,
|
||||
Allow: true,
|
||||
})
|
||||
} else if peer.Address6.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: peer.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
DstIP: *ipNet,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
if len(peer.StaticNode.ExtraAllowedIPs) > 0 {
|
||||
for _, additionalAllowedIPNet := range peer.StaticNode.ExtraAllowedIPs {
|
||||
_, ipNet, err := net.ParseCIDR(additionalAllowedIPNet)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if ipNet.IP.To4() != nil && node.Address.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
DstIP: *ipNet,
|
||||
Allow: true,
|
||||
})
|
||||
} else if node.Address6.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
DstIP: *ipNet,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// add egress range rules
|
||||
for _, dstI := range policy.Dst {
|
||||
if dstI.ID == models.EgressID {
|
||||
|
||||
e := schema.Egress{ID: dstI.Value}
|
||||
err := e.Get(db.WithContext(context.TODO()))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
dstI.Value = e.Range
|
||||
|
||||
ip, cidr, err := net.ParseCIDR(dstI.Value)
|
||||
if err == nil {
|
||||
if ip.To4() != nil {
|
||||
if node.Address.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
DstIP: *cidr,
|
||||
AllowedProtocol: policy.Proto,
|
||||
AllowedPorts: policy.Port,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if node.Address6.IP != nil {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: net.IPNet{
|
||||
IP: node.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
DstIP: *cidr,
|
||||
AllowedProtocol: policy.Proto,
|
||||
AllowedPorts: policy.Port,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []models.FwRule) {
|
||||
defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
||||
userNodes := GetStaticUserNodesByNetwork(models.NetworkID(node.Network))
|
||||
for _, userNodeI := range userNodes {
|
||||
for _, peer := range nodes {
|
||||
if peer.IsUserNode {
|
||||
continue
|
||||
}
|
||||
|
||||
if ok, allowedPolicies := IsUserAllowedToCommunicate(userNodeI.StaticNode.OwnerID, peer); ok {
|
||||
if peer.IsStatic {
|
||||
peer = peer.StaticNode.ConvertToStaticNode()
|
||||
}
|
||||
if !defaultUserPolicy.Enabled {
|
||||
for _, policy := range allowedPolicies {
|
||||
if userNodeI.StaticNode.Address != "" {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: userNodeI.StaticNode.AddressIPNet4(),
|
||||
DstIP: net.IPNet{
|
||||
IP: peer.Address.IP,
|
||||
Mask: net.CIDRMask(32, 32),
|
||||
},
|
||||
AllowedProtocol: policy.Proto,
|
||||
AllowedPorts: policy.Port,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
if userNodeI.StaticNode.Address6 != "" {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: userNodeI.StaticNode.AddressIPNet6(),
|
||||
DstIP: net.IPNet{
|
||||
IP: peer.Address6.IP,
|
||||
Mask: net.CIDRMask(128, 128),
|
||||
},
|
||||
AllowedProtocol: policy.Proto,
|
||||
AllowedPorts: policy.Port,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
|
||||
// add egress ranges
|
||||
for _, dstI := range policy.Dst {
|
||||
if dstI.ID == models.EgressID {
|
||||
|
||||
e := schema.Egress{ID: dstI.Value}
|
||||
err := e.Get(db.WithContext(context.TODO()))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
dstI.Value = e.Range
|
||||
|
||||
ip, cidr, err := net.ParseCIDR(dstI.Value)
|
||||
if err == nil {
|
||||
if ip.To4() != nil && userNodeI.StaticNode.Address != "" {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: userNodeI.StaticNode.AddressIPNet4(),
|
||||
DstIP: *cidr,
|
||||
AllowedProtocol: policy.Proto,
|
||||
AllowedPorts: policy.Port,
|
||||
Allow: true,
|
||||
})
|
||||
} else if ip.To16() != nil && userNodeI.StaticNode.Address6 != "" {
|
||||
rules = append(rules, models.FwRule{
|
||||
SrcIP: userNodeI.StaticNode.AddressIPNet6(),
|
||||
DstIP: *cidr,
|
||||
AllowedProtocol: policy.Proto,
|
||||
AllowedPorts: policy.Port,
|
||||
Allow: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
|
||||
// fetch user access to static clients via policies
|
||||
defer func() {
|
||||
sort.Slice(rules, func(i, j int) bool {
|
||||
if !rules[i].SrcIP.IP.Equal(rules[j].SrcIP.IP) {
|
||||
return string(rules[i].SrcIP.IP.To16()) < string(rules[j].SrcIP.IP.To16())
|
||||
}
|
||||
return string(rules[i].DstIP.IP.To16()) < string(rules[j].DstIP.IP.To16())
|
||||
})
|
||||
}()
|
||||
defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
||||
nodes, _ := GetNetworkNodes(node.Network)
|
||||
nodes = append(nodes, GetStaticNodesByNetwork(models.NetworkID(node.Network), true)...)
|
||||
rules = getFwRulesForUserNodesOnGw(node, nodes)
|
||||
if defaultDevicePolicy.Enabled {
|
||||
return
|
||||
}
|
||||
for _, nodeI := range nodes {
|
||||
if !nodeI.IsStatic || nodeI.IsUserNode {
|
||||
continue
|
||||
}
|
||||
// if nodeI.StaticNode.IngressGatewayID != node.ID.String() {
|
||||
// continue
|
||||
// }
|
||||
for _, peer := range nodes {
|
||||
if peer.StaticNode.ClientID == nodeI.StaticNode.ClientID || peer.IsUserNode {
|
||||
continue
|
||||
}
|
||||
if nodeI.StaticNode.IngressGatewayID != node.ID.String() &&
|
||||
((!peer.IsStatic && peer.ID.String() != node.ID.String()) ||
|
||||
(peer.IsStatic && peer.StaticNode.IngressGatewayID != node.ID.String())) {
|
||||
continue
|
||||
}
|
||||
if peer.IsStatic {
|
||||
peer = peer.StaticNode.ConvertToStaticNode()
|
||||
}
|
||||
var allowedPolicies1 []models.Acl
|
||||
var ok bool
|
||||
if ok, allowedPolicies1 = IsNodeAllowedToCommunicateV1(nodeI.StaticNode.ConvertToStaticNode(), peer, true); ok {
|
||||
rules = append(rules, getFwRulesForNodeAndPeerOnGw(nodeI.StaticNode.ConvertToStaticNode(), peer, allowedPolicies1)...)
|
||||
}
|
||||
if ok, allowedPolicies2 := IsNodeAllowedToCommunicateV1(peer, nodeI.StaticNode.ConvertToStaticNode(), true); ok {
|
||||
rules = append(rules,
|
||||
getFwRulesForNodeAndPeerOnGw(peer, nodeI.StaticNode.ConvertToStaticNode(),
|
||||
GetUniquePolicies(allowedPolicies1, allowedPolicies2))...)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetUniquePolicies(policies1, policies2 []models.Acl) []models.Acl {
|
||||
policies1Map := make(map[string]struct{})
|
||||
for _, policy1I := range policies1 {
|
||||
policies1Map[policy1I.ID] = struct{}{}
|
||||
}
|
||||
for i := len(policies2) - 1; i >= 0; i-- {
|
||||
if _, ok := policies1Map[policies2[i].ID]; ok {
|
||||
policies2 = append(policies2[:i], policies2[i+1:]...)
|
||||
}
|
||||
}
|
||||
return policies2
|
||||
}
|
||||
|
||||
func GetExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, []models.EgressNetworkRoutes, error) {
|
||||
var peers []wgtypes.PeerConfig
|
||||
var idsAndAddr []models.IDandAddr
|
||||
@@ -964,7 +627,7 @@ func getExtpeerEgressRanges(node models.Node) (ranges, ranges6 []net.IPNet) {
|
||||
if len(extPeer.ExtraAllowedIPs) == 0 {
|
||||
continue
|
||||
}
|
||||
if ok, _ := IsNodeAllowedToCommunicateV1(extPeer.ConvertToStaticNode(), node, true); !ok {
|
||||
if ok, _ := IsNodeAllowedToCommunicate(extPeer.ConvertToStaticNode(), node, true); !ok {
|
||||
continue
|
||||
}
|
||||
for _, allowedRange := range extPeer.ExtraAllowedIPs {
|
||||
@@ -991,7 +654,7 @@ func getExtpeersExtraRoutes(node models.Node) (egressRoutes []models.EgressNetwo
|
||||
if len(extPeer.ExtraAllowedIPs) == 0 {
|
||||
continue
|
||||
}
|
||||
if ok, _ := IsNodeAllowedToCommunicateV1(extPeer.ConvertToStaticNode(), node, true); !ok {
|
||||
if ok, _ := IsNodeAllowedToCommunicate(extPeer.ConvertToStaticNode(), node, true); !ok {
|
||||
continue
|
||||
}
|
||||
egressRoutes = append(egressRoutes, getExtPeerEgressRoute(node, extPeer)...)
|
||||
|
@@ -229,6 +229,12 @@ func CreateHost(h *models.Host) error {
|
||||
}
|
||||
h.HostPass = string(hash)
|
||||
h.AutoUpdate = AutoUpdateEnabled()
|
||||
|
||||
if GetServerSettings().ManageDNS {
|
||||
h.DNS = "on"
|
||||
} else {
|
||||
h.DNS = "off"
|
||||
}
|
||||
checkForZombieHosts(h)
|
||||
return UpsertHost(h)
|
||||
}
|
||||
|
294
logic/nodes.go
294
logic/nodes.go
@@ -30,6 +30,8 @@ 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) {
|
||||
@@ -641,14 +643,6 @@ func createNode(node *models.Node) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if !node.DNSOn {
|
||||
if servercfg.IsDNSMode() {
|
||||
node.DNSOn = true
|
||||
} else {
|
||||
node.DNSOn = false
|
||||
}
|
||||
}
|
||||
|
||||
SetNodeDefaults(node, true)
|
||||
|
||||
defaultACLVal := acls.Allowed
|
||||
@@ -833,206 +827,156 @@ func GetAllFailOvers() ([]models.Node, error) {
|
||||
return igs, nil
|
||||
}
|
||||
|
||||
func GetTagMapWithNodes() (tagNodesMap map[models.TagID][]models.Node) {
|
||||
tagNodesMap = make(map[models.TagID][]models.Node)
|
||||
nodes, _ := GetAllNodes()
|
||||
for _, nodeI := range nodes {
|
||||
if nodeI.Tags == nil {
|
||||
continue
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Lock()
|
||||
}
|
||||
for nodeTagID := range nodeI.Tags {
|
||||
tagNodesMap[nodeTagID] = append(tagNodesMap[nodeTagID], nodeI)
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Unlock()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetTagMapWithNodesByNetwork(netID models.NetworkID, withStaticNodes bool) (tagNodesMap map[models.TagID][]models.Node) {
|
||||
tagNodesMap = make(map[models.TagID][]models.Node)
|
||||
nodes, _ := GetNetworkNodes(netID.String())
|
||||
for _, nodeI := range nodes {
|
||||
tagNodesMap[models.TagID(nodeI.ID.String())] = []models.Node{
|
||||
nodeI,
|
||||
for _, clientNodeID := range req.InetNodeClientIDs {
|
||||
clientNode, err := GetNodeByID(clientNodeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if nodeI.Tags == nil {
|
||||
continue
|
||||
if clientNode.IsFailOver {
|
||||
return errors.New("failover node cannot be set to use internet gateway")
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Lock()
|
||||
clientHost, err := GetHost(clientNode.HostID.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for nodeTagID := range nodeI.Tags {
|
||||
if nodeTagID == models.TagID(nodeI.ID.String()) {
|
||||
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
|
||||
}
|
||||
tagNodesMap[nodeTagID] = append(tagNodesMap[nodeTagID], nodeI)
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Unlock()
|
||||
}
|
||||
}
|
||||
tagNodesMap["*"] = nodes
|
||||
if !withStaticNodes {
|
||||
return
|
||||
}
|
||||
return AddTagMapWithStaticNodes(netID, tagNodesMap)
|
||||
}
|
||||
|
||||
func AddTagMapWithStaticNodes(netID models.NetworkID,
|
||||
tagNodesMap map[models.TagID][]models.Node) map[models.TagID][]models.Node {
|
||||
extclients, err := GetNetworkExtClients(netID.String())
|
||||
if err != nil {
|
||||
return tagNodesMap
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
if extclient.RemoteAccessClientID != "" {
|
||||
continue
|
||||
}
|
||||
tagNodesMap[models.TagID(extclient.ClientID)] = []models.Node{
|
||||
{
|
||||
IsStatic: true,
|
||||
StaticNode: extclient,
|
||||
},
|
||||
}
|
||||
if extclient.Tags == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Lock()
|
||||
}
|
||||
for tagID := range extclient.Tags {
|
||||
if tagID == models.TagID(extclient.ClientID) {
|
||||
continue
|
||||
if node.EgressDetails.InternetGwID != "" && node.EgressDetails.InternetGwID != inetNode.ID.String() {
|
||||
return errors.New("nodes on same host cannot use different internet gateway")
|
||||
}
|
||||
tagNodesMap[tagID] = append(tagNodesMap[tagID], extclient.ConvertToStaticNode())
|
||||
tagNodesMap["*"] = append(tagNodesMap["*"], extclient.ConvertToStaticNode())
|
||||
}
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Unlock()
|
||||
|
||||
}
|
||||
}
|
||||
return tagNodesMap
|
||||
return nil
|
||||
}
|
||||
|
||||
func AddTagMapWithStaticNodesWithUsers(netID models.NetworkID,
|
||||
tagNodesMap map[models.TagID][]models.Node) map[models.TagID][]models.Node {
|
||||
extclients, err := GetNetworkExtClients(netID.String())
|
||||
if err != nil {
|
||||
return tagNodesMap
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
tagNodesMap[models.TagID(extclient.ClientID)] = []models.Node{
|
||||
{
|
||||
IsStatic: true,
|
||||
StaticNode: extclient,
|
||||
},
|
||||
}
|
||||
if extclient.Tags == 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
|
||||
}
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Lock()
|
||||
}
|
||||
for tagID := range extclient.Tags {
|
||||
tagNodesMap[tagID] = append(tagNodesMap[tagID], extclient.ConvertToStaticNode())
|
||||
}
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Unlock()
|
||||
}
|
||||
|
||||
clientNode.EgressDetails.InternetGwID = node.ID.String()
|
||||
UpsertNode(&clientNode)
|
||||
}
|
||||
return tagNodesMap
|
||||
|
||||
}
|
||||
|
||||
func GetNodeIDsWithTag(tagID models.TagID) (ids []string) {
|
||||
|
||||
tag, err := GetTag(tagID)
|
||||
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
|
||||
}
|
||||
nodes, _ := GetNetworkNodes(tag.Network.String())
|
||||
for _, nodeI := range nodes {
|
||||
if nodeI.Tags == nil {
|
||||
continue
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Lock()
|
||||
}
|
||||
if _, ok := nodeI.Tags[tagID]; ok {
|
||||
ids = append(ids, nodeI.ID.String())
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Unlock()
|
||||
for _, clientNode := range nodes {
|
||||
if node.ID.String() == clientNode.EgressDetails.InternetGwID {
|
||||
clientNode.EgressDetails.InternetGwID = ""
|
||||
UpsertNode(&clientNode)
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
node.EgressDetails.IsInternetGateway = false
|
||||
node.EgressDetails.InetNodeReq = models.InetNodeReq{}
|
||||
|
||||
}
|
||||
|
||||
func GetNodesWithTag(tagID models.TagID) map[string]models.Node {
|
||||
nMap := make(map[string]models.Node)
|
||||
tag, err := GetTag(tagID)
|
||||
if err != nil {
|
||||
return nMap
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
nodes, _ := GetNetworkNodes(tag.Network.String())
|
||||
for _, nodeI := range nodes {
|
||||
if nodeI.Tags == nil {
|
||||
continue
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Lock()
|
||||
}
|
||||
if _, ok := nodeI.Tags[tagID]; ok {
|
||||
nMap[nodeI.ID.String()] = nodeI
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Unlock()
|
||||
}
|
||||
}
|
||||
return AddStaticNodesWithTag(tag, nMap)
|
||||
return peerUpdate
|
||||
}
|
||||
|
||||
func AddStaticNodesWithTag(tag models.Tag, nMap map[string]models.Node) map[string]models.Node {
|
||||
extclients, err := GetNetworkExtClients(tag.Network.String())
|
||||
if err != nil {
|
||||
return nMap
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
if extclient.RemoteAccessClientID != "" {
|
||||
continue
|
||||
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
|
||||
}
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Lock()
|
||||
host, err := GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
return peerUpdate
|
||||
}
|
||||
if _, ok := extclient.Tags[tag.ID]; ok {
|
||||
nMap[extclient.ClientID] = extclient.ConvertToStaticNode()
|
||||
}
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Unlock()
|
||||
|
||||
peerUpdate.ChangeDefaultGw = true
|
||||
peerUpdate.DefaultGwIp = inetNode.Address.IP
|
||||
if peerUpdate.DefaultGwIp == nil || host.EndpointIP == nil {
|
||||
peerUpdate.DefaultGwIp = inetNode.Address6.IP
|
||||
}
|
||||
}
|
||||
return nMap
|
||||
return peerUpdate
|
||||
}
|
||||
|
||||
func GetStaticNodeWithTag(tagID models.TagID) map[string]models.Node {
|
||||
nMap := make(map[string]models.Node)
|
||||
tag, err := GetTag(tagID)
|
||||
if err != nil {
|
||||
return nMap
|
||||
// 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)
|
||||
}
|
||||
extclients, err := GetNetworkExtClients(tag.Network.String())
|
||||
if err != nil {
|
||||
return nMap
|
||||
|
||||
if peer.Address6.IP != nil {
|
||||
_, ipnet, _ := net.ParseCIDR(IPv6Network)
|
||||
allowedips = append(allowedips, *ipnet)
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
nMap[extclient.ClientID] = extclient.ConvertToStaticNode()
|
||||
}
|
||||
return nMap
|
||||
|
||||
return allowedips
|
||||
}
|
||||
|
@@ -39,29 +39,6 @@ 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.EgressDetails.IsInternetGateway = false
|
||||
}
|
||||
// SetInternetGw
|
||||
SetInternetGw = func(node *models.Node, req models.InetNodeReq) {
|
||||
node.EgressDetails.IsInternetGateway = true
|
||||
}
|
||||
// GetAllowedIpForInetNodeClient
|
||||
GetAllowedIpForInetNodeClient = func(node, peer *models.Node) []net.IPNet {
|
||||
return []net.IPNet{}
|
||||
}
|
||||
ValidateInetGwReq = func(inetNode models.Node, req models.InetNodeReq, update bool) error {
|
||||
return nil
|
||||
}
|
||||
)
|
||||
|
||||
// GetHostPeerInfo - fetches required peer info per network
|
||||
@@ -111,7 +88,7 @@ func GetHostPeerInfo(host *models.Host) (models.HostPeerInfo, error) {
|
||||
!peer.PendingDelete &&
|
||||
peer.Connected &&
|
||||
nodeacls.AreNodesAllowed(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), nodeacls.NodeID(peer.ID.String())) &&
|
||||
(defaultDevicePolicy.Enabled || allowedToComm) {
|
||||
(allowedToComm) {
|
||||
|
||||
networkPeersInfo[peerHost.PublicKey.String()] = models.IDandAddr{
|
||||
ID: peer.ID.String(),
|
||||
@@ -164,6 +141,9 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
||||
HostNetworkInfo: models.HostInfoMap{},
|
||||
ServerConfig: GetServerInfo(),
|
||||
}
|
||||
if host.DNS == "off" {
|
||||
hostPeerUpdate.ManageDNS = false
|
||||
}
|
||||
defer func() {
|
||||
if !hostPeerUpdate.FwUpdate.AllowAll {
|
||||
|
||||
@@ -203,10 +183,12 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
||||
}
|
||||
defaultUserPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
|
||||
defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
|
||||
|
||||
anyActiveEgressPolicy := CheckIfAnyActiveEgressPolicy(node)
|
||||
nodeHasAccessToAllRsrcs := CheckIfNodeHasAccessToAllResources(&node)
|
||||
anyUniDirectionPolicy := CheckIfAnyPolicyisUniDirectional(node)
|
||||
if (defaultDevicePolicy.Enabled && defaultUserPolicy.Enabled) ||
|
||||
(!checkIfAnyPolicyisUniDirectional(node) && !checkIfAnyActiveEgressPolicy(node)) ||
|
||||
checkIfNodeHasAccessToAllResources(&node) {
|
||||
(!anyUniDirectionPolicy && !anyActiveEgressPolicy) ||
|
||||
nodeHasAccessToAllRsrcs {
|
||||
aclRule := models.AclRule{
|
||||
ID: fmt.Sprintf("%s-allowed-network-rules", node.ID.String()),
|
||||
AllowedProtocol: models.ALL,
|
||||
@@ -371,8 +353,8 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
||||
!peer.PendingDelete &&
|
||||
peer.Connected &&
|
||||
nodeacls.AreNodesAllowed(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), nodeacls.NodeID(peer.ID.String())) &&
|
||||
(defaultDevicePolicy.Enabled || allowedToComm) &&
|
||||
(deletedNode == nil || (deletedNode != nil && peer.ID.String() != deletedNode.ID.String())) {
|
||||
(allowedToComm) &&
|
||||
(deletedNode == nil || (peer.ID.String() != deletedNode.ID.String())) {
|
||||
peerConfig.AllowedIPs = GetAllowedIPs(&node, &peer, nil) // only append allowed IPs if valid connection
|
||||
}
|
||||
|
||||
|
@@ -222,6 +222,10 @@ func GetAllowedIpsForRelayed(relayed, relay *models.Node) (allowedIPs []net.IPNe
|
||||
if peer.ID == relayed.ID || peer.ID == relay.ID {
|
||||
continue
|
||||
}
|
||||
if !IsPeerAllowed(*relayed, peer, true) {
|
||||
continue
|
||||
}
|
||||
GetNodeEgressInfo(&peer)
|
||||
if nodeacls.AreNodesAllowed(nodeacls.NetworkID(relayed.Network), nodeacls.NodeID(relayed.ID.String()), nodeacls.NodeID(peer.ID.String())) {
|
||||
allowedIPs = append(allowedIPs, GetAllowedIPs(relayed, &peer, nil)...)
|
||||
}
|
||||
|
@@ -102,25 +102,6 @@ func ListPlatformRoles() ([]models.UserRolePermissionTemplate, error) {
|
||||
return userRoles, nil
|
||||
}
|
||||
|
||||
func GetUserGrpMap() map[models.UserGroupID]map[string]struct{} {
|
||||
grpUsersMap := make(map[models.UserGroupID]map[string]struct{})
|
||||
users, _ := GetUsersDB()
|
||||
for _, user := range users {
|
||||
for gID := range user.UserGroups {
|
||||
if grpUsers, ok := grpUsersMap[gID]; ok {
|
||||
grpUsers[user.UserName] = struct{}{}
|
||||
grpUsersMap[gID] = grpUsers
|
||||
} else {
|
||||
grpUsersMap[gID] = make(map[string]struct{})
|
||||
grpUsersMap[gID][user.UserName] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return grpUsersMap
|
||||
}
|
||||
|
||||
func userRolesInit() {
|
||||
d, _ := json.Marshal(SuperAdminPermissionTemplate)
|
||||
database.Insert(SuperAdminPermissionTemplate.ID.String(), string(d), database.USER_PERMISSIONS_TABLE_NAME)
|
||||
|
@@ -34,7 +34,7 @@ func Run() {
|
||||
updateHosts()
|
||||
updateNodes()
|
||||
updateAcls()
|
||||
migrateToGws()
|
||||
logic.MigrateToGws()
|
||||
migrateToEgressV1()
|
||||
}
|
||||
|
||||
@@ -196,6 +196,13 @@ func updateHosts() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if host.DNS == "" {
|
||||
if logic.GetServerSettings().ManageDNS {
|
||||
host.DNS = "on"
|
||||
} else {
|
||||
host.DNS = "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,51 +472,6 @@ func createDefaultTagsAndPolicies() {
|
||||
logic.MigrateAclPolicies()
|
||||
}
|
||||
|
||||
func migrateToGws() {
|
||||
nodes, err := logic.GetAllNodes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, node := range nodes {
|
||||
if node.IsIngressGateway || node.IsRelay {
|
||||
node.IsGw = true
|
||||
node.IsIngressGateway = true
|
||||
node.IsRelay = true
|
||||
if node.Tags == nil {
|
||||
node.Tags = make(map[models.TagID]struct{})
|
||||
}
|
||||
node.Tags[models.TagID(fmt.Sprintf("%s.%s", node.Network, models.GwTagName))] = struct{}{}
|
||||
delete(node.Tags, models.TagID(fmt.Sprintf("%s.%s", node.Network, models.OldRemoteAccessTagName)))
|
||||
logic.UpsertNode(&node)
|
||||
}
|
||||
}
|
||||
acls := logic.ListAcls()
|
||||
for _, acl := range acls {
|
||||
upsert := false
|
||||
for i, srcI := range acl.Src {
|
||||
if srcI.ID == models.NodeTagID && srcI.Value == fmt.Sprintf("%s.%s", acl.NetworkID.String(), models.OldRemoteAccessTagName) {
|
||||
srcI.Value = fmt.Sprintf("%s.%s", acl.NetworkID.String(), models.GwTagName)
|
||||
acl.Src[i] = srcI
|
||||
upsert = true
|
||||
}
|
||||
}
|
||||
for i, dstI := range acl.Dst {
|
||||
if dstI.ID == models.NodeTagID && dstI.Value == fmt.Sprintf("%s.%s", acl.NetworkID.String(), models.OldRemoteAccessTagName) {
|
||||
dstI.Value = fmt.Sprintf("%s.%s", acl.NetworkID.String(), models.GwTagName)
|
||||
acl.Dst[i] = dstI
|
||||
upsert = true
|
||||
}
|
||||
}
|
||||
if upsert {
|
||||
logic.UpsertAcl(acl)
|
||||
}
|
||||
}
|
||||
nets, _ := logic.GetNetworks()
|
||||
for _, netI := range nets {
|
||||
logic.DeleteTag(models.TagID(fmt.Sprintf("%s.%s", netI.NetID, models.OldRemoteAccessTagName)), true)
|
||||
}
|
||||
}
|
||||
|
||||
func migrateToEgressV1() {
|
||||
nodes, _ := logic.GetAllNodes()
|
||||
user, err := logic.GetSuperAdmin()
|
||||
|
@@ -31,6 +31,7 @@ type ApiHost struct {
|
||||
NatType string `json:"nat_type" yaml:"nat_type"`
|
||||
PersistentKeepalive int `json:"persistentkeepalive" yaml:"persistentkeepalive"`
|
||||
AutoUpdate bool `json:"autoupdate" yaml:"autoupdate"`
|
||||
DNS string `json:"dns" yaml:"dns"`
|
||||
}
|
||||
|
||||
// ApiIface - the interface struct for API usage
|
||||
@@ -78,6 +79,7 @@ func (h *Host) ConvertNMHostToAPI() *ApiHost {
|
||||
a.NatType = h.NatType
|
||||
a.PersistentKeepalive = int(h.PersistentKeepalive.Seconds())
|
||||
a.AutoUpdate = h.AutoUpdate
|
||||
a.DNS = h.DNS
|
||||
return &a
|
||||
}
|
||||
|
||||
@@ -123,5 +125,6 @@ func (a *ApiHost) ConvertAPIHostToNMHost(currentHost *Host) *Host {
|
||||
h.TurnEndpoint = currentHost.TurnEndpoint
|
||||
h.PersistentKeepalive = time.Duration(a.PersistentKeepalive) * time.Second
|
||||
h.AutoUpdate = a.AutoUpdate
|
||||
h.DNS = a.DNS
|
||||
return &h
|
||||
}
|
||||
|
@@ -32,6 +32,7 @@ type ApiNode struct {
|
||||
NetworkRange6 string `json:"networkrange6"`
|
||||
IsRelayed bool `json:"isrelayed"`
|
||||
IsRelay bool `json:"isrelay"`
|
||||
IsGw bool `json:"is_gw"`
|
||||
RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"`
|
||||
RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"`
|
||||
IsEgressGateway bool `json:"isegressgateway"`
|
||||
@@ -72,17 +73,16 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
|
||||
convertedNode.Connected = a.Connected
|
||||
convertedNode.ID, _ = uuid.Parse(a.ID)
|
||||
convertedNode.HostID, _ = uuid.Parse(a.HostID)
|
||||
convertedNode.IsRelay = a.IsRelay
|
||||
//convertedNode.IsRelay = a.IsRelay
|
||||
convertedNode.IsRelayed = a.IsRelayed
|
||||
convertedNode.RelayedBy = a.RelayedBy
|
||||
convertedNode.RelayedNodes = a.RelayedNodes
|
||||
convertedNode.PendingDelete = a.PendingDelete
|
||||
convertedNode.FailedOverBy = currentNode.FailedOverBy
|
||||
convertedNode.FailOverPeers = currentNode.FailOverPeers
|
||||
convertedNode.IsIngressGateway = a.IsIngressGateway
|
||||
//convertedNode.IsIngressGateway = a.IsIngressGateway
|
||||
convertedNode.IngressGatewayRange = currentNode.IngressGatewayRange
|
||||
convertedNode.IngressGatewayRange6 = currentNode.IngressGatewayRange6
|
||||
convertedNode.DNSOn = a.DNSOn
|
||||
convertedNode.IngressDNS = a.IngressDns
|
||||
convertedNode.IngressPersistentKeepalive = a.IngressPersistentKeepalive
|
||||
convertedNode.IngressMTU = a.IngressMTU
|
||||
@@ -132,6 +132,11 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
|
||||
convertedNode.AdditionalRagIps = append(convertedNode.AdditionalRagIps, ragIp)
|
||||
}
|
||||
convertedNode.Tags = a.Tags
|
||||
convertedNode.IsGw = a.IsGw
|
||||
if convertedNode.IsGw {
|
||||
convertedNode.IsRelay = true
|
||||
convertedNode.IsIngressGateway = true
|
||||
}
|
||||
return &convertedNode
|
||||
}
|
||||
|
||||
@@ -180,10 +185,10 @@ func (nm *Node) ConvertToAPINode() *ApiNode {
|
||||
}
|
||||
apiNode.IsRelayed = nm.IsRelayed
|
||||
apiNode.IsRelay = nm.IsRelay
|
||||
apiNode.IsGw = nm.IsGw
|
||||
apiNode.RelayedBy = nm.RelayedBy
|
||||
apiNode.RelayedNodes = nm.RelayedNodes
|
||||
apiNode.IsIngressGateway = nm.IsIngressGateway
|
||||
apiNode.DNSOn = nm.DNSOn
|
||||
apiNode.IngressDns = nm.IngressDNS
|
||||
apiNode.IngressPersistentKeepalive = nm.IngressPersistentKeepalive
|
||||
apiNode.IngressMTU = nm.IngressMTU
|
||||
|
@@ -69,6 +69,7 @@ type Host struct {
|
||||
IsStaticPort bool `json:"isstaticport" yaml:"isstaticport"`
|
||||
IsStatic bool `json:"isstatic" yaml:"isstatic"`
|
||||
IsDefault bool `json:"isdefault" yaml:"isdefault"`
|
||||
DNS string `json:"dns_status" yaml:"dns_status"`
|
||||
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" swaggertype:"primitive,integer" format:"int64" yaml:"persistentkeepalive"`
|
||||
|
@@ -87,7 +87,6 @@ type CommonNode struct {
|
||||
IsGw bool `json:"is_gw" yaml:"is_gw"`
|
||||
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
|
||||
@@ -482,6 +481,12 @@ func (newNode *Node) Fill(
|
||||
if newNode.IsFailOver != currentNode.IsFailOver {
|
||||
newNode.IsFailOver = currentNode.IsFailOver
|
||||
}
|
||||
if newNode.Tags == nil {
|
||||
if currentNode.Tags == nil {
|
||||
currentNode.Tags = make(map[TagID]struct{})
|
||||
}
|
||||
newNode.Tags = currentNode.Tags
|
||||
}
|
||||
}
|
||||
|
||||
// StringWithCharset - returns random string inside defined charset
|
||||
@@ -572,7 +577,6 @@ func (ln *LegacyNode) ConvertToNewNode() (*Host, *Node) {
|
||||
}
|
||||
node.Action = ln.Action
|
||||
node.IsIngressGateway = parseBool(ln.IsIngressGateway)
|
||||
node.DNSOn = parseBool(ln.DNSOn)
|
||||
|
||||
return &host, &node
|
||||
}
|
||||
@@ -613,7 +617,6 @@ func (n *Node) Legacy(h *Host, s *ServerConfig, net *Network) *LegacyNode {
|
||||
//l.IngressGatewayRange6 = n.IngressGatewayRange6
|
||||
l.IsStatic = formatBool(h.IsStatic)
|
||||
l.UDPHolePunch = formatBool(true)
|
||||
l.DNSOn = formatBool(n.DNSOn)
|
||||
l.Action = n.Action
|
||||
l.IPForwarding = formatBool(h.IPForwarding)
|
||||
l.OS = h.OS
|
||||
|
@@ -70,12 +70,12 @@ func createInternetGw(w http.ResponseWriter, r *http.Request) {
|
||||
)
|
||||
return
|
||||
}
|
||||
err = proLogic.ValidateInetGwReq(node, request, false)
|
||||
err = logic.ValidateInetGwReq(node, request, false)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
proLogic.SetInternetGw(&node, request)
|
||||
logic.SetInternetGw(&node, request)
|
||||
if servercfg.IsPro {
|
||||
if _, exists := proLogic.FailOverExists(node.Network); exists {
|
||||
go func() {
|
||||
@@ -140,13 +140,13 @@ func updateInternetGw(w http.ResponseWriter, r *http.Request) {
|
||||
)
|
||||
return
|
||||
}
|
||||
err = proLogic.ValidateInetGwReq(node, request, true)
|
||||
err = logic.ValidateInetGwReq(node, request, true)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
proLogic.UnsetInternetGw(&node)
|
||||
proLogic.SetInternetGw(&node, request)
|
||||
logic.UnsetInternetGw(&node)
|
||||
logic.SetInternetGw(&node, request)
|
||||
err = logic.UpsertNode(&node)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
@@ -185,7 +185,7 @@ func deleteInternetGw(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
proLogic.UnsetInternetGw(&node)
|
||||
logic.UnsetInternetGw(&node)
|
||||
err = logic.UpsertNode(&node)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
|
@@ -1,4 +1,4 @@
|
||||
package controller
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@@ -14,9 +14,10 @@ import (
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
proLogic "github.com/gravitl/netmaker/pro/logic"
|
||||
)
|
||||
|
||||
func tagHandlers(r *mux.Router) {
|
||||
func TagHandlers(r *mux.Router) {
|
||||
r.HandleFunc("/api/v1/tags", logic.SecurityCheck(true, http.HandlerFunc(getTags))).
|
||||
Methods(http.MethodGet)
|
||||
r.HandleFunc("/api/v1/tags", logic.SecurityCheck(true, http.HandlerFunc(createTag))).
|
||||
@@ -46,13 +47,13 @@ func getTags(w http.ResponseWriter, r *http.Request) {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
tags, err := logic.ListTagsWithNodes(models.NetworkID(netID))
|
||||
tags, err := proLogic.ListTagsWithNodes(models.NetworkID(netID))
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to get all network tag entries: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
logic.SortTagEntrys(tags[:])
|
||||
proLogic.SortTagEntrys(tags[:])
|
||||
logic.ReturnSuccessResponseWithJson(w, r, tags, "fetched all tags in the network "+netID)
|
||||
}
|
||||
|
||||
@@ -91,18 +92,18 @@ func createTag(w http.ResponseWriter, r *http.Request) {
|
||||
ColorCode: req.ColorCode,
|
||||
CreatedAt: time.Now().UTC(),
|
||||
}
|
||||
_, err = logic.GetTag(tag.ID)
|
||||
_, err = proLogic.GetTag(tag.ID)
|
||||
if err == nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("tag with id %s exists already", tag.TagName), "badrequest"))
|
||||
return
|
||||
}
|
||||
// validate name
|
||||
err = logic.CheckIDSyntax(tag.TagName)
|
||||
err = proLogic.CheckIDSyntax(tag.TagName)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
err = logic.InsertTag(tag)
|
||||
err = proLogic.InsertTag(tag)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
@@ -174,7 +175,7 @@ func updateTag(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
tag, err := logic.GetTag(updateTag.ID)
|
||||
tag, err := proLogic.GetTag(updateTag.ID)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
@@ -202,7 +203,7 @@ func updateTag(w http.ResponseWriter, r *http.Request) {
|
||||
var newID models.TagID
|
||||
if updateTag.NewName != "" {
|
||||
// validate name
|
||||
err = logic.CheckIDSyntax(updateTag.NewName)
|
||||
err = proLogic.CheckIDSyntax(updateTag.NewName)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
@@ -210,26 +211,26 @@ func updateTag(w http.ResponseWriter, r *http.Request) {
|
||||
newID = models.TagID(fmt.Sprintf("%s.%s", tag.Network, updateTag.NewName))
|
||||
tag.ID = newID
|
||||
tag.TagName = updateTag.NewName
|
||||
err = logic.InsertTag(tag)
|
||||
err = proLogic.InsertTag(tag)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
// delete old Tag entry
|
||||
logic.DeleteTag(updateTag.ID, false)
|
||||
proLogic.DeleteTag(updateTag.ID, false)
|
||||
}
|
||||
if updateTag.ColorCode != "" && updateTag.ColorCode != tag.ColorCode {
|
||||
tag.ColorCode = updateTag.ColorCode
|
||||
err = logic.UpsertTag(tag)
|
||||
err = proLogic.UpsertTag(tag)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
logic.UpdateTag(updateTag, newID)
|
||||
proLogic.UpdateTag(updateTag, newID)
|
||||
if updateTag.NewName != "" {
|
||||
logic.UpdateDeviceTag(updateTag.ID, newID, tag.Network)
|
||||
proLogic.UpdateDeviceTag(updateTag.ID, newID, tag.Network)
|
||||
}
|
||||
mq.PublishPeerUpdate(false)
|
||||
}()
|
||||
@@ -256,24 +257,24 @@ func deleteTag(w http.ResponseWriter, r *http.Request) {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
|
||||
return
|
||||
}
|
||||
tag, err := logic.GetTag(models.TagID(tagID))
|
||||
tag, err := proLogic.GetTag(models.TagID(tagID))
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
// check if active policy is using the tag
|
||||
if logic.CheckIfTagAsActivePolicy(tag.ID, tag.Network) {
|
||||
if proLogic.CheckIfTagAsActivePolicy(tag.ID, tag.Network) {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("tag is currently in use by an active policy"), "badrequest"))
|
||||
return
|
||||
}
|
||||
err = logic.DeleteTag(models.TagID(tagID), true)
|
||||
err = proLogic.DeleteTag(models.TagID(tagID), true)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
logic.RemoveDeviceTagFromAclPolicies(tag.ID, tag.Network)
|
||||
proLogic.RemoveDeviceTagFromAclPolicies(tag.ID, tag.Network)
|
||||
logic.RemoveTagFromEnrollmentKeys(tag.ID)
|
||||
mq.PublishPeerUpdate(false)
|
||||
}()
|
@@ -35,6 +35,7 @@ func InitPro() {
|
||||
proControllers.InetHandlers,
|
||||
proControllers.RacHandlers,
|
||||
proControllers.EventHandlers,
|
||||
proControllers.TagHandlers,
|
||||
)
|
||||
controller.ListRoles = proControllers.ListRoles
|
||||
logic.EnterpriseCheckFuncs = append(logic.EnterpriseCheckFuncs, func() {
|
||||
@@ -112,12 +113,6 @@ func InitPro() {
|
||||
logic.UpdateMetrics = proLogic.UpdateMetrics
|
||||
logic.DeleteMetrics = proLogic.DeleteMetrics
|
||||
logic.GetTrialEndDate = getTrialEndDate
|
||||
logic.SetDefaultGw = proLogic.SetDefaultGw
|
||||
logic.ValidateInetGwReq = proLogic.ValidateInetGwReq
|
||||
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
|
||||
@@ -146,6 +141,23 @@ func InitPro() {
|
||||
logic.ResetIDPSyncHook = auth.ResetIDPSyncHook
|
||||
logic.EmailInit = email.Init
|
||||
logic.LogEvent = proLogic.LogEvent
|
||||
logic.RemoveUserFromAclPolicy = proLogic.RemoveUserFromAclPolicy
|
||||
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
|
||||
logic.GetEgressRulesForNode = proLogic.GetEgressRulesForNode
|
||||
logic.GetAclRulesForNode = proLogic.GetAclRulesForNode
|
||||
logic.CheckIfAnyActiveEgressPolicy = proLogic.CheckIfAnyActiveEgressPolicy
|
||||
logic.CheckIfAnyPolicyisUniDirectional = proLogic.CheckIfAnyPolicyisUniDirectional
|
||||
logic.MigrateToGws = proLogic.MigrateToGws
|
||||
logic.IsNodeAllowedToCommunicate = proLogic.IsNodeAllowedToCommunicate
|
||||
logic.GetStaticNodeIps = proLogic.GetStaticNodeIps
|
||||
logic.GetFwRulesOnIngressGateway = proLogic.GetFwRulesOnIngressGateway
|
||||
|
||||
}
|
||||
|
||||
func retrieveProLogo() string {
|
||||
|
1930
pro/logic/acls.go
Normal file
1930
pro/logic/acls.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,8 @@ package logic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitl/netmaker/database"
|
||||
|
||||
@@ -254,3 +256,48 @@ func MigrateUserRoleAndGroups(user models.User) {
|
||||
}
|
||||
logic.UpsertUser(user)
|
||||
}
|
||||
|
||||
func MigrateToGws() {
|
||||
nodes, err := logic.GetAllNodes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, node := range nodes {
|
||||
if node.IsIngressGateway || node.IsRelay {
|
||||
node.IsGw = true
|
||||
node.IsIngressGateway = true
|
||||
node.IsRelay = true
|
||||
if node.Tags == nil {
|
||||
node.Tags = make(map[models.TagID]struct{})
|
||||
}
|
||||
node.Tags[models.TagID(fmt.Sprintf("%s.%s", node.Network, models.GwTagName))] = struct{}{}
|
||||
delete(node.Tags, models.TagID(fmt.Sprintf("%s.%s", node.Network, models.OldRemoteAccessTagName)))
|
||||
logic.UpsertNode(&node)
|
||||
}
|
||||
}
|
||||
acls := logic.ListAcls()
|
||||
for _, acl := range acls {
|
||||
upsert := false
|
||||
for i, srcI := range acl.Src {
|
||||
if srcI.ID == models.NodeTagID && srcI.Value == fmt.Sprintf("%s.%s", acl.NetworkID.String(), models.OldRemoteAccessTagName) {
|
||||
srcI.Value = fmt.Sprintf("%s.%s", acl.NetworkID.String(), models.GwTagName)
|
||||
acl.Src[i] = srcI
|
||||
upsert = true
|
||||
}
|
||||
}
|
||||
for i, dstI := range acl.Dst {
|
||||
if dstI.ID == models.NodeTagID && dstI.Value == fmt.Sprintf("%s.%s", acl.NetworkID.String(), models.OldRemoteAccessTagName) {
|
||||
dstI.Value = fmt.Sprintf("%s.%s", acl.NetworkID.String(), models.GwTagName)
|
||||
acl.Dst[i] = dstI
|
||||
upsert = true
|
||||
}
|
||||
}
|
||||
if upsert {
|
||||
logic.UpsertAcl(acl)
|
||||
}
|
||||
}
|
||||
nets, _ := logic.GetNetworks()
|
||||
for _, netI := range nets {
|
||||
DeleteTag(models.TagID(fmt.Sprintf("%s.%s", netI.NetID, models.OldRemoteAccessTagName)), true)
|
||||
}
|
||||
}
|
||||
|
@@ -1,158 +1,10 @@
|
||||
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"
|
||||
)
|
||||
|
||||
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 bool
|
||||
func 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 network
|
||||
func GetNetworkIngresses(network string) ([]models.Node, error) {
|
||||
var ingresses []models.Node
|
||||
@@ -168,19 +20,206 @@ func GetNetworkIngresses(network string) ([]models.Node, error) {
|
||||
return ingresses, nil
|
||||
}
|
||||
|
||||
// GetAllowedIpForInetNodeClient - get inet cidr for node using a inet gw
|
||||
func GetAllowedIpForInetNodeClient(node, peer *models.Node) []net.IPNet {
|
||||
var allowedips = []net.IPNet{}
|
||||
func GetTagMapWithNodes() (tagNodesMap map[models.TagID][]models.Node) {
|
||||
tagNodesMap = make(map[models.TagID][]models.Node)
|
||||
nodes, _ := logic.GetAllNodes()
|
||||
for _, nodeI := range nodes {
|
||||
if nodeI.Tags == nil {
|
||||
continue
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Lock()
|
||||
}
|
||||
for nodeTagID := range nodeI.Tags {
|
||||
tagNodesMap[nodeTagID] = append(tagNodesMap[nodeTagID], nodeI)
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Unlock()
|
||||
}
|
||||
|
||||
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
|
||||
return
|
||||
}
|
||||
|
||||
func GetTagMapWithNodesByNetwork(netID models.NetworkID, withStaticNodes bool) (tagNodesMap map[models.TagID][]models.Node) {
|
||||
tagNodesMap = make(map[models.TagID][]models.Node)
|
||||
nodes, _ := logic.GetNetworkNodes(netID.String())
|
||||
for _, nodeI := range nodes {
|
||||
tagNodesMap[models.TagID(nodeI.ID.String())] = []models.Node{
|
||||
nodeI,
|
||||
}
|
||||
if nodeI.Tags == nil {
|
||||
continue
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Lock()
|
||||
}
|
||||
for nodeTagID := range nodeI.Tags {
|
||||
if nodeTagID == models.TagID(nodeI.ID.String()) {
|
||||
continue
|
||||
}
|
||||
tagNodesMap[nodeTagID] = append(tagNodesMap[nodeTagID], nodeI)
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Unlock()
|
||||
}
|
||||
}
|
||||
tagNodesMap["*"] = nodes
|
||||
if !withStaticNodes {
|
||||
return
|
||||
}
|
||||
return AddTagMapWithStaticNodes(netID, tagNodesMap)
|
||||
}
|
||||
|
||||
func AddTagMapWithStaticNodes(netID models.NetworkID,
|
||||
tagNodesMap map[models.TagID][]models.Node) map[models.TagID][]models.Node {
|
||||
extclients, err := logic.GetNetworkExtClients(netID.String())
|
||||
if err != nil {
|
||||
return tagNodesMap
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
if extclient.RemoteAccessClientID != "" {
|
||||
continue
|
||||
}
|
||||
tagNodesMap[models.TagID(extclient.ClientID)] = []models.Node{
|
||||
{
|
||||
IsStatic: true,
|
||||
StaticNode: extclient,
|
||||
},
|
||||
}
|
||||
if extclient.Tags == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Lock()
|
||||
}
|
||||
for tagID := range extclient.Tags {
|
||||
if tagID == models.TagID(extclient.ClientID) {
|
||||
continue
|
||||
}
|
||||
tagNodesMap[tagID] = append(tagNodesMap[tagID], extclient.ConvertToStaticNode())
|
||||
tagNodesMap["*"] = append(tagNodesMap["*"], extclient.ConvertToStaticNode())
|
||||
}
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Unlock()
|
||||
}
|
||||
}
|
||||
return tagNodesMap
|
||||
}
|
||||
|
||||
func AddTagMapWithStaticNodesWithUsers(netID models.NetworkID,
|
||||
tagNodesMap map[models.TagID][]models.Node) map[models.TagID][]models.Node {
|
||||
extclients, err := logic.GetNetworkExtClients(netID.String())
|
||||
if err != nil {
|
||||
return tagNodesMap
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
tagNodesMap[models.TagID(extclient.ClientID)] = []models.Node{
|
||||
{
|
||||
IsStatic: true,
|
||||
StaticNode: extclient,
|
||||
},
|
||||
}
|
||||
if extclient.Tags == nil {
|
||||
continue
|
||||
}
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Lock()
|
||||
}
|
||||
for tagID := range extclient.Tags {
|
||||
tagNodesMap[tagID] = append(tagNodesMap[tagID], extclient.ConvertToStaticNode())
|
||||
}
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Unlock()
|
||||
}
|
||||
|
||||
}
|
||||
return tagNodesMap
|
||||
}
|
||||
|
||||
func GetNodeIDsWithTag(tagID models.TagID) (ids []string) {
|
||||
|
||||
tag, err := GetTag(tagID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
nodes, _ := logic.GetNetworkNodes(tag.Network.String())
|
||||
for _, nodeI := range nodes {
|
||||
if nodeI.Tags == nil {
|
||||
continue
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Lock()
|
||||
}
|
||||
if _, ok := nodeI.Tags[tagID]; ok {
|
||||
ids = append(ids, nodeI.ID.String())
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Unlock()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetNodesWithTag(tagID models.TagID) map[string]models.Node {
|
||||
nMap := make(map[string]models.Node)
|
||||
tag, err := GetTag(tagID)
|
||||
if err != nil {
|
||||
return nMap
|
||||
}
|
||||
nodes, _ := logic.GetNetworkNodes(tag.Network.String())
|
||||
for _, nodeI := range nodes {
|
||||
if nodeI.Tags == nil {
|
||||
continue
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Lock()
|
||||
}
|
||||
if _, ok := nodeI.Tags[tagID]; ok {
|
||||
nMap[nodeI.ID.String()] = nodeI
|
||||
}
|
||||
if nodeI.Mutex != nil {
|
||||
nodeI.Mutex.Unlock()
|
||||
}
|
||||
}
|
||||
return AddStaticNodesWithTag(tag, nMap)
|
||||
}
|
||||
|
||||
func AddStaticNodesWithTag(tag models.Tag, nMap map[string]models.Node) map[string]models.Node {
|
||||
extclients, err := logic.GetNetworkExtClients(tag.Network.String())
|
||||
if err != nil {
|
||||
return nMap
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
if extclient.RemoteAccessClientID != "" {
|
||||
continue
|
||||
}
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Lock()
|
||||
}
|
||||
if _, ok := extclient.Tags[tag.ID]; ok {
|
||||
nMap[extclient.ClientID] = extclient.ConvertToStaticNode()
|
||||
}
|
||||
if extclient.Mutex != nil {
|
||||
extclient.Mutex.Unlock()
|
||||
}
|
||||
}
|
||||
return nMap
|
||||
}
|
||||
|
||||
func GetStaticNodeWithTag(tagID models.TagID) map[string]models.Node {
|
||||
nMap := make(map[string]models.Node)
|
||||
tag, err := GetTag(tagID)
|
||||
if err != nil {
|
||||
return nMap
|
||||
}
|
||||
extclients, err := logic.GetNetworkExtClients(tag.Network.String())
|
||||
if err != nil {
|
||||
return nMap
|
||||
}
|
||||
for _, extclient := range extclients {
|
||||
nMap[extclient.ClientID] = extclient.ConvertToStaticNode()
|
||||
}
|
||||
return nMap
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ func GetNodeStatus(node *models.Node, defaultEnabledPolicy bool) {
|
||||
return
|
||||
}
|
||||
if !defaultEnabledPolicy {
|
||||
allowed, _ := logic.IsNodeAllowedToCommunicateV1(*node, ingNode, false)
|
||||
allowed, _ := logic.IsNodeAllowedToCommunicate(*node, ingNode, false)
|
||||
if !allowed {
|
||||
node.Status = models.OnlineSt
|
||||
return
|
||||
@@ -161,7 +161,7 @@ func checkPeerStatus(node *models.Node, defaultAclPolicy bool) {
|
||||
}
|
||||
|
||||
if !defaultAclPolicy {
|
||||
allowed, _ := logic.IsNodeAllowedToCommunicateV1(*node, peer, false)
|
||||
allowed, _ := logic.IsNodeAllowedToCommunicate(*node, peer, false)
|
||||
if !allowed {
|
||||
continue
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func checkPeerConnectivity(node *models.Node, metrics *models.Metrics, defaultAc
|
||||
}
|
||||
|
||||
if !defaultAclPolicy {
|
||||
allowed, _ := logic.IsNodeAllowedToCommunicateV1(*node, peer, false)
|
||||
allowed, _ := logic.IsNodeAllowedToCommunicate(*node, peer, false)
|
||||
if !allowed {
|
||||
continue
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"golang.org/x/exp/slog"
|
||||
)
|
||||
@@ -62,7 +63,7 @@ func DeleteTag(tagID models.TagID, removeFromPolicy bool) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nodes, err := GetNetworkNodes(tag.Network.String())
|
||||
nodes, err := logic.GetNetworkNodes(tag.Network.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -70,18 +71,18 @@ func DeleteTag(tagID models.TagID, removeFromPolicy bool) error {
|
||||
nodeI := nodeI
|
||||
if _, ok := nodeI.Tags[tagID]; ok {
|
||||
delete(nodeI.Tags, tagID)
|
||||
UpsertNode(&nodeI)
|
||||
logic.UpsertNode(&nodeI)
|
||||
}
|
||||
}
|
||||
if removeFromPolicy {
|
||||
// remove tag used on acl policy
|
||||
go RemoveDeviceTagFromAclPolicies(tagID, tag.Network)
|
||||
}
|
||||
extclients, _ := GetNetworkExtClients(tag.Network.String())
|
||||
extclients, _ := logic.GetNetworkExtClients(tag.Network.String())
|
||||
for _, extclient := range extclients {
|
||||
if _, ok := extclient.Tags[tagID]; ok {
|
||||
delete(extclient.Tags, tagID)
|
||||
SaveExtClient(&extclient)
|
||||
logic.SaveExtClient(&extclient)
|
||||
}
|
||||
}
|
||||
return database.DeleteRecord(database.TAG_TABLE_NAME, tagID.String())
|
||||
@@ -99,7 +100,7 @@ func ListTagsWithNodes(netID models.NetworkID) ([]models.TagListResp, error) {
|
||||
tagRespI := models.TagListResp{
|
||||
Tag: tagI,
|
||||
UsedByCnt: len(tagsNodeMap[tagI.ID]),
|
||||
TaggedNodes: GetAllNodesAPI(tagsNodeMap[tagI.ID]),
|
||||
TaggedNodes: logic.GetAllNodesAPI(tagsNodeMap[tagI.ID]),
|
||||
}
|
||||
resp = append(resp, tagRespI)
|
||||
}
|
||||
@@ -168,7 +169,7 @@ func UpdateTag(req models.UpdateTagReq, newID models.TagID) {
|
||||
if apiNode.StaticNode.RemoteAccessClientID != "" {
|
||||
continue
|
||||
}
|
||||
extclient, err := GetExtClient(apiNode.StaticNode.ClientID, apiNode.StaticNode.Network)
|
||||
extclient, err := logic.GetExtClient(apiNode.StaticNode.ClientID, apiNode.StaticNode.Network)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
@@ -176,7 +177,7 @@ func UpdateTag(req models.UpdateTagReq, newID models.TagID) {
|
||||
nodeID = extclient.ClientID
|
||||
node.StaticNode = extclient
|
||||
} else {
|
||||
node, err = GetNodeByID(apiNode.ID)
|
||||
node, err = logic.GetNodeByID(apiNode.ID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
@@ -193,19 +194,19 @@ func UpdateTag(req models.UpdateTagReq, newID models.TagID) {
|
||||
if newID != "" {
|
||||
if node.IsStatic {
|
||||
node.StaticNode.Tags[newID] = struct{}{}
|
||||
SaveExtClient(&node.StaticNode)
|
||||
logic.SaveExtClient(&node.StaticNode)
|
||||
} else {
|
||||
node.Tags[newID] = struct{}{}
|
||||
UpsertNode(&node)
|
||||
logic.UpsertNode(&node)
|
||||
}
|
||||
|
||||
} else {
|
||||
if node.IsStatic {
|
||||
node.StaticNode.Tags[req.ID] = struct{}{}
|
||||
SaveExtClient(&node.StaticNode)
|
||||
logic.SaveExtClient(&node.StaticNode)
|
||||
} else {
|
||||
node.Tags[req.ID] = struct{}{}
|
||||
UpsertNode(&node)
|
||||
logic.UpsertNode(&node)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -214,10 +215,10 @@ func UpdateTag(req models.UpdateTagReq, newID models.TagID) {
|
||||
delete(node.StaticNode.Tags, req.ID)
|
||||
if node.IsStatic {
|
||||
node.StaticNode.Tags[newID] = struct{}{}
|
||||
SaveExtClient(&node.StaticNode)
|
||||
logic.SaveExtClient(&node.StaticNode)
|
||||
} else {
|
||||
node.Tags[newID] = struct{}{}
|
||||
UpsertNode(&node)
|
||||
logic.UpsertNode(&node)
|
||||
}
|
||||
}
|
||||
delete(tagNodesMap, nodeID)
|
||||
@@ -228,9 +229,9 @@ func UpdateTag(req models.UpdateTagReq, newID models.TagID) {
|
||||
delete(deletedTaggedNode.Tags, req.ID)
|
||||
delete(deletedTaggedNode.StaticNode.Tags, req.ID)
|
||||
if deletedTaggedNode.IsStatic {
|
||||
SaveExtClient(&deletedTaggedNode.StaticNode)
|
||||
logic.SaveExtClient(&deletedTaggedNode.StaticNode)
|
||||
} else {
|
||||
UpsertNode(&deletedTaggedNode)
|
||||
logic.UpsertNode(&deletedTaggedNode)
|
||||
}
|
||||
}
|
||||
go func(req models.UpdateTagReq) {
|
||||
@@ -249,9 +250,9 @@ func UpdateTag(req models.UpdateTagReq, newID models.TagID) {
|
||||
nodeI.Tags[newID] = struct{}{}
|
||||
nodeI.StaticNode.Tags[newID] = struct{}{}
|
||||
if nodeI.IsStatic {
|
||||
SaveExtClient(&nodeI.StaticNode)
|
||||
logic.SaveExtClient(&nodeI.StaticNode)
|
||||
} else {
|
||||
UpsertNode(&nodeI)
|
||||
logic.UpsertNode(&nodeI)
|
||||
}
|
||||
}
|
||||
}
|
@@ -4,9 +4,10 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/google/uuid"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/gravitl/netmaker/database"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
@@ -688,8 +689,8 @@ func GetUserRAGNodesV1(user models.User) (gws map[string]models.Node) {
|
||||
|
||||
}
|
||||
}
|
||||
tagNodesMap := logic.GetTagMapWithNodes()
|
||||
accessPolices := logic.ListUserPolicies(user)
|
||||
tagNodesMap := GetTagMapWithNodes()
|
||||
accessPolices := ListUserPolicies(user)
|
||||
for _, policyI := range accessPolices {
|
||||
if !policyI.Enabled {
|
||||
continue
|
||||
@@ -722,9 +723,33 @@ func GetUserRAGNodes(user models.User) (gws map[string]models.Node) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
if ok, _ := logic.IsUserAllowedToCommunicate(user.UserName, node); ok {
|
||||
if !node.IsGw {
|
||||
continue
|
||||
}
|
||||
if user.PlatformRoleID == models.AdminRole || user.PlatformRoleID == models.SuperAdminRole {
|
||||
gws[node.ID.String()] = node
|
||||
} else {
|
||||
// check if user has network role assigned
|
||||
if roles, ok := user.NetworkRoles[models.NetworkID(node.Network)]; ok && len(roles) > 0 {
|
||||
if ok, _ := IsUserAllowedToCommunicate(user.UserName, node); ok {
|
||||
gws[node.ID.String()] = node
|
||||
continue
|
||||
}
|
||||
}
|
||||
for groupID := range user.UserGroups {
|
||||
userGrp, err := logic.GetUserGroup(groupID)
|
||||
if err == nil {
|
||||
if roles, ok := userGrp.NetworkRoles[models.NetworkID(node.Network)]; ok && len(roles) > 0 {
|
||||
if ok, _ := IsUserAllowedToCommunicate(user.UserName, node); ok {
|
||||
gws[node.ID.String()] = node
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -1169,6 +1194,35 @@ func CreateDefaultUserPolicies(netID models.NetworkID) {
|
||||
return
|
||||
}
|
||||
|
||||
if !logic.IsAclExists(fmt.Sprintf("%s.%s", netID, "all-users")) {
|
||||
defaultUserAcl := models.Acl{
|
||||
ID: fmt.Sprintf("%s.%s", netID, "all-users"),
|
||||
Default: true,
|
||||
Name: "All Users",
|
||||
MetaData: "This policy gives access to everything in the network for an user",
|
||||
NetworkID: netID,
|
||||
Proto: models.ALL,
|
||||
ServiceType: models.Any,
|
||||
Port: []string{},
|
||||
RuleType: models.UserPolicy,
|
||||
Src: []models.AclPolicyTag{
|
||||
{
|
||||
ID: models.UserAclID,
|
||||
Value: "*",
|
||||
},
|
||||
},
|
||||
Dst: []models.AclPolicyTag{{
|
||||
ID: models.NodeTagID,
|
||||
Value: "*",
|
||||
}},
|
||||
AllowedDirection: models.TrafficDirectionUni,
|
||||
Enabled: true,
|
||||
CreatedBy: "auto",
|
||||
CreatedAt: time.Now().UTC(),
|
||||
}
|
||||
logic.InsertAcl(defaultUserAcl)
|
||||
}
|
||||
|
||||
if !logic.IsAclExists(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin)) {
|
||||
networkAdminGroupID := GetDefaultNetworkAdminGroupID(netID)
|
||||
|
||||
@@ -1268,3 +1322,22 @@ func AddGlobalNetRolesToAdmins(u *models.User) {
|
||||
|
||||
u.UserGroups[globalNetworksAdminGroupID] = struct{}{}
|
||||
}
|
||||
|
||||
func GetUserGrpMap() map[models.UserGroupID]map[string]struct{} {
|
||||
grpUsersMap := make(map[models.UserGroupID]map[string]struct{})
|
||||
users, _ := logic.GetUsersDB()
|
||||
for _, user := range users {
|
||||
for gID := range user.UserGroups {
|
||||
if grpUsers, ok := grpUsersMap[gID]; ok {
|
||||
grpUsers[user.UserName] = struct{}{}
|
||||
grpUsersMap[gID] = grpUsers
|
||||
} else {
|
||||
grpUsersMap[gID] = make(map[string]struct{})
|
||||
grpUsersMap[gID][user.UserName] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return grpUsersMap
|
||||
}
|
||||
|
@@ -685,7 +685,7 @@ func GetMetricInterval() string {
|
||||
|
||||
// GetManageDNS - if manage DNS enabled or not
|
||||
func GetManageDNS() bool {
|
||||
enabled := false
|
||||
enabled := true
|
||||
if os.Getenv("MANAGE_DNS") != "" {
|
||||
enabled = os.Getenv("MANAGE_DNS") == "true"
|
||||
}
|
||||
|
Reference in New Issue
Block a user