Browse Source

Merge pull request #2697 from gravitl/master

master
Abhishek K 1 year ago
parent
commit
5efa52279d
8 changed files with 178 additions and 76 deletions
  1. 3 0
      controllers/ext_client.go
  2. 110 3
      logic/extpeers.go
  3. 1 1
      logic/jwts.go
  4. 7 72
      logic/peers.go
  5. 14 0
      logic/util.go
  6. 22 0
      migrate/migrate.go
  7. 16 0
      models/node.go
  8. 5 0
      servercfg/serverconf.go

+ 3 - 0
controllers/ext_client.go

@@ -481,6 +481,9 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
 		sendPeerUpdate = true
 		logic.SetClientACLs(&oldExtClient, update.DeniedACLs)
 	}
+	if !logic.IsSlicesEqual(update.ExtraAllowedIPs, oldExtClient.ExtraAllowedIPs) {
+		sendPeerUpdate = true
+	}
 
 	if update.Enabled != oldExtClient.Enabled {
 		sendPeerUpdate = true

+ 110 - 3
logic/extpeers.go

@@ -3,11 +3,13 @@ package logic
 import (
 	"encoding/json"
 	"fmt"
+	"net"
 	"reflect"
 	"sync"
 	"time"
 
 	"github.com/gravitl/netmaker/database"
+	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/models"
 	"golang.org/x/exp/slog"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
@@ -184,6 +186,9 @@ func CreateExtClient(extclient *models.ExtClient) error {
 	} else if len(extclient.PrivateKey) == 0 && len(extclient.PublicKey) > 0 {
 		extclient.PrivateKey = "[ENTER PRIVATE KEY]"
 	}
+	if extclient.ExtraAllowedIPs == nil {
+		extclient.ExtraAllowedIPs = []string{}
+	}
 
 	parentNetwork, err := GetNetwork(extclient.Network)
 	if err != nil {
@@ -247,9 +252,7 @@ func UpdateExtClient(old *models.ExtClient, update *models.CustomExtClient) mode
 	if update.Enabled != old.Enabled {
 		new.Enabled = update.Enabled
 	}
-	if update.ExtraAllowedIPs != nil && StringDifference(old.ExtraAllowedIPs, update.ExtraAllowedIPs) != nil {
-		new.ExtraAllowedIPs = update.ExtraAllowedIPs
-	}
+	new.ExtraAllowedIPs = update.ExtraAllowedIPs
 	if update.DeniedACLs != nil && !reflect.DeepEqual(old.DeniedACLs, update.DeniedACLs) {
 		new.DeniedACLs = update.DeniedACLs
 	}
@@ -318,3 +321,107 @@ func ToggleExtClientConnectivity(client *models.ExtClient, enable bool) (models.
 
 	return newClient, nil
 }
+
+func getExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, []models.EgressNetworkRoutes, error) {
+	var peers []wgtypes.PeerConfig
+	var idsAndAddr []models.IDandAddr
+	var egressRoutes []models.EgressNetworkRoutes
+	extPeers, err := GetNetworkExtClients(node.Network)
+	if err != nil {
+		return peers, idsAndAddr, egressRoutes, err
+	}
+	host, err := GetHost(node.HostID.String())
+	if err != nil {
+		return peers, idsAndAddr, egressRoutes, err
+	}
+	for _, extPeer := range extPeers {
+		extPeer := extPeer
+		if !IsClientNodeAllowed(&extPeer, peer.ID.String()) {
+			continue
+		}
+		pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
+		if err != nil {
+			logger.Log(1, "error parsing ext pub key:", err.Error())
+			continue
+		}
+
+		if host.PublicKey.String() == extPeer.PublicKey ||
+			extPeer.IngressGatewayID != node.ID.String() || !extPeer.Enabled {
+			continue
+		}
+
+		var allowedips []net.IPNet
+		var peer wgtypes.PeerConfig
+		if extPeer.Address != "" {
+			var peeraddr = net.IPNet{
+				IP:   net.ParseIP(extPeer.Address),
+				Mask: net.CIDRMask(32, 32),
+			}
+			if peeraddr.IP != nil && peeraddr.Mask != nil {
+				allowedips = append(allowedips, peeraddr)
+			}
+		}
+
+		if extPeer.Address6 != "" {
+			var addr6 = net.IPNet{
+				IP:   net.ParseIP(extPeer.Address6),
+				Mask: net.CIDRMask(128, 128),
+			}
+			if addr6.IP != nil && addr6.Mask != nil {
+				allowedips = append(allowedips, addr6)
+			}
+		}
+		for _, extraAllowedIP := range extPeer.ExtraAllowedIPs {
+			_, cidr, err := net.ParseCIDR(extraAllowedIP)
+			if err == nil {
+				allowedips = append(allowedips, *cidr)
+			}
+		}
+		egressRoutes = append(egressRoutes, getExtPeerEgressRoute(extPeer)...)
+		primaryAddr := extPeer.Address
+		if primaryAddr == "" {
+			primaryAddr = extPeer.Address6
+		}
+		peer = wgtypes.PeerConfig{
+			PublicKey:         pubkey,
+			ReplaceAllowedIPs: true,
+			AllowedIPs:        allowedips,
+		}
+		peers = append(peers, peer)
+		idsAndAddr = append(idsAndAddr, models.IDandAddr{
+			ID:          peer.PublicKey.String(),
+			Name:        extPeer.ClientID,
+			Address:     primaryAddr,
+			IsExtClient: true,
+		})
+	}
+	return peers, idsAndAddr, egressRoutes, nil
+
+}
+
+func getExtPeerEgressRoute(extPeer models.ExtClient) (egressRoutes []models.EgressNetworkRoutes) {
+	if extPeer.Address != "" {
+		egressRoutes = append(egressRoutes, models.EgressNetworkRoutes{
+			NodeAddr:     extPeer.AddressIPNet4(),
+			EgressRanges: extPeer.ExtraAllowedIPs,
+		})
+	}
+	if extPeer.Address6 != "" {
+		egressRoutes = append(egressRoutes, models.EgressNetworkRoutes{
+			NodeAddr:     extPeer.AddressIPNet6(),
+			EgressRanges: extPeer.ExtraAllowedIPs,
+		})
+	}
+	return
+}
+
+func getExtpeersExtraRoutes(network string) (egressRoutes []models.EgressNetworkRoutes) {
+	extPeers, err := GetNetworkExtClients(network)
+	if err != nil {
+		return
+	}
+	for _, extPeer := range extPeers {
+		egressRoutes = append(egressRoutes, getExtPeerEgressRoute(extPeer)...)
+	}
+	return
+}

+ 1 - 1
logic/jwts.go

@@ -108,7 +108,7 @@ func VerifyUserToken(tokenString string) (username string, issuperadmin, isadmin
 		}
 
 		if user.UserName != "" {
-			return claims.UserName, claims.IsSuperAdmin, claims.IsAdmin, nil
+			return user.UserName, user.IsSuperAdmin, user.IsAdmin, nil
 		}
 		err = errors.New("user does not exist")
 	}

+ 7 - 72
logic/peers.go

@@ -129,6 +129,9 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 					EgressRanges: peer.EgressGatewayRanges,
 				})
 			}
+			if peer.IsIngressGateway {
+				hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(peer.Network)...)
+			}
 			if (node.IsRelayed && node.RelayedBy != peer.ID.String()) || (peer.IsRelayed && peer.RelayedBy != node.ID.String()) {
 				// if node is relayed and peer is not the relay, set remove to true
 				if _, ok := peerIndexMap[peerHost.PublicKey.String()]; ok {
@@ -207,9 +210,11 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 		}
 		var extPeers []wgtypes.PeerConfig
 		var extPeerIDAndAddrs []models.IDandAddr
+		var egressRoutes []models.EgressNetworkRoutes
 		if node.IsIngressGateway {
-			extPeers, extPeerIDAndAddrs, err = getExtPeers(&node, &node)
+			extPeers, extPeerIDAndAddrs, egressRoutes, err = getExtPeers(&node, &node)
 			if err == nil {
+				hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, egressRoutes...)
 				hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
 				for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
 					extPeerIdAndAddr := extPeerIdAndAddr
@@ -290,76 +295,6 @@ func GetPeerListenPort(host *models.Host) int {
 	return peerPort
 }
 
-func getExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, error) {
-	var peers []wgtypes.PeerConfig
-	var idsAndAddr []models.IDandAddr
-	extPeers, err := GetNetworkExtClients(node.Network)
-	if err != nil {
-		return peers, idsAndAddr, err
-	}
-	host, err := GetHost(node.HostID.String())
-	if err != nil {
-		return peers, idsAndAddr, err
-	}
-	for _, extPeer := range extPeers {
-		extPeer := extPeer
-		if !IsClientNodeAllowed(&extPeer, peer.ID.String()) {
-			continue
-		}
-		pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
-		if err != nil {
-			logger.Log(1, "error parsing ext pub key:", err.Error())
-			continue
-		}
-
-		if host.PublicKey.String() == extPeer.PublicKey ||
-			extPeer.IngressGatewayID != node.ID.String() || !extPeer.Enabled {
-			continue
-		}
-
-		var allowedips []net.IPNet
-		var peer wgtypes.PeerConfig
-		if extPeer.Address != "" {
-			var peeraddr = net.IPNet{
-				IP:   net.ParseIP(extPeer.Address),
-				Mask: net.CIDRMask(32, 32),
-			}
-			if peeraddr.IP != nil && peeraddr.Mask != nil {
-				allowedips = append(allowedips, peeraddr)
-			}
-		}
-
-		if extPeer.Address6 != "" {
-			var addr6 = net.IPNet{
-				IP:   net.ParseIP(extPeer.Address6),
-				Mask: net.CIDRMask(128, 128),
-			}
-			if addr6.IP != nil && addr6.Mask != nil {
-				allowedips = append(allowedips, addr6)
-			}
-		}
-
-		primaryAddr := extPeer.Address
-		if primaryAddr == "" {
-			primaryAddr = extPeer.Address6
-		}
-		peer = wgtypes.PeerConfig{
-			PublicKey:         pubkey,
-			ReplaceAllowedIPs: true,
-			AllowedIPs:        allowedips,
-		}
-		peers = append(peers, peer)
-		idsAndAddr = append(idsAndAddr, models.IDandAddr{
-			ID:          peer.PublicKey.String(),
-			Name:        extPeer.ClientID,
-			Address:     primaryAddr,
-			IsExtClient: true,
-		})
-	}
-	return peers, idsAndAddr, nil
-
-}
-
 // GetAllowedIPs - calculates the wireguard allowedip field for a peer of a node based on the peer and node settings
 func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet {
 	var allowedips []net.IPNet
@@ -367,7 +302,7 @@ func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet
 
 	// handle ingress gateway peers
 	if peer.IsIngressGateway {
-		extPeers, _, err := getExtPeers(peer, node)
+		extPeers, _, _, err := getExtPeers(peer, node)
 		if err != nil {
 			logger.Log(2, "could not retrieve ext peers for ", peer.ID.String(), err.Error())
 		}

+ 14 - 0
logic/util.go

@@ -134,4 +134,18 @@ func RemoveStringSlice(slice []string, i int) []string {
 	return append(slice[:i], slice[i+1:]...)
 }
 
+// IsSlicesEqual tells whether a and b contain the same elements.
+// A nil argument is equivalent to an empty slice.
+func IsSlicesEqual(a, b []string) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i, v := range a {
+		if v != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
 // == private ==

+ 22 - 0
migrate/migrate.go

@@ -2,6 +2,7 @@ package migrate
 
 import (
 	"encoding/json"
+	"log"
 
 	"golang.org/x/exp/slog"
 
@@ -9,6 +10,7 @@ import (
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
+	"github.com/gravitl/netmaker/servercfg"
 )
 
 // Run - runs all migrations
@@ -28,6 +30,26 @@ func assignSuperAdmin() {
 		return
 	}
 	createdSuperAdmin := false
+	owner := servercfg.GetOwnerEmail()
+	if owner != "" {
+		user, err := logic.GetUser(owner)
+		if err != nil {
+			log.Fatal("error getting user", "user", owner, "error", err.Error())
+		}
+		user.IsSuperAdmin = true
+		user.IsAdmin = false
+		err = logic.UpsertUser(*user)
+		if err != nil {
+			log.Fatal(
+				"error updating user to superadmin",
+				"user",
+				user.UserName,
+				"error",
+				err.Error(),
+			)
+		}
+		return
+	}
 	for _, u := range users {
 		if u.IsAdmin {
 			user, err := logic.GetUser(u.UserName)

+ 16 - 0
models/node.go

@@ -192,6 +192,22 @@ func (node *Node) PrimaryAddress() string {
 	return node.Address6.IP.String()
 }
 
+// ExtClient.PrimaryAddress - returns ipv4 IPNet format
+func (extPeer *ExtClient) AddressIPNet4() net.IPNet {
+	return net.IPNet{
+		IP:   net.ParseIP(extPeer.Address),
+		Mask: net.CIDRMask(32, 32),
+	}
+}
+
+// ExtClient.AddressIPNet6 - return ipv6 IPNet format
+func (extPeer *ExtClient) AddressIPNet6() net.IPNet {
+	return net.IPNet{
+		IP:   net.ParseIP(extPeer.Address),
+		Mask: net.CIDRMask(128, 128),
+	}
+}
+
 // Node.PrimaryNetworkRange - returns node's parent network, returns ipv4 address if present, else return ipv6
 func (node *Node) PrimaryNetworkRange() net.IPNet {
 	if node.NetworkRange.IP != nil {

+ 5 - 0
servercfg/serverconf.go

@@ -256,6 +256,11 @@ func GetPublicBrokerEndpoint() string {
 	}
 }
 
+// GetOwnerEmail - gets the owner email (saas)
+func GetOwnerEmail() string {
+	return os.Getenv("SAAS_OWNER_EMAIL")
+}
+
 // GetMessageQueueEndpoint - gets the message queue endpoint
 func GetMessageQueueEndpoint() (string, bool) {
 	host, _ := GetPublicIP()