Browse Source

merge conflicts

0xdcarns 2 years ago
parent
commit
c257827807
9 changed files with 125 additions and 53 deletions
  1. 3 4
      controllers/ext_client.go
  2. 20 4
      controllers/node.go
  3. 1 1
      logic/gateway.go
  4. 12 3
      logic/hosts.go
  5. 10 8
      logic/nodes.go
  6. 38 24
      logic/peers.go
  7. 18 0
      models/host.go
  8. 3 3
      mq/handlers.go
  9. 20 6
      mq/publishers.go

+ 3 - 4
controllers/ext_client.go

@@ -214,7 +214,7 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
 	if network.DefaultKeepalive != 0 {
 		keepalive = "PersistentKeepalive = " + strconv.Itoa(int(network.DefaultKeepalive))
 	}
-	gwendpoint := gwnode.EndpointIP.String() + ":" + strconv.Itoa(host.ListenPort)
+	gwendpoint := host.EndpointIP.String() + ":" + strconv.Itoa(host.ListenPort)
 	newAllowedIPs := network.AddressRange
 	if newAllowedIPs != "" && network.AddressRange6 != "" {
 		newAllowedIPs += ","
@@ -338,12 +338,11 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
 	logger.Log(0, r.Header.Get("user"),
 		fmt.Sprintf("failed to get ingress gateway host for node [%s] info: %v", nodeid, err))
 	logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
-	return
 	listenPort := host.LocalListenPort
-	if node.Proxy {
+	if host.ProxyEnabled {
 		listenPort = host.ProxyListenPort
 	}
-	extclient.IngressGatewayEndpoint = node.EndpointIP.String() + ":" + strconv.FormatInt(int64(listenPort), 10)
+	extclient.IngressGatewayEndpoint = host.EndpointIP.String() + ":" + strconv.FormatInt(int64(listenPort), 10)
 
 	extclient.Enabled = true
 	parentNetwork, err := logic.GetNetwork(networkName)

+ 20 - 4
controllers/node.go

@@ -95,6 +95,14 @@ func authenticate(response http.ResponseWriter, request *http.Request) {
 		}
 	}
 	host, err := logic.GetHost(result.HostID.String())
+	if err != nil {
+		errorResponse.Code = http.StatusBadRequest
+		errorResponse.Message = err.Error()
+		logger.Log(0, request.Header.Get("user"),
+			"error retrieving host: ", err.Error())
+		logic.ReturnErrorResponse(response, request, errorResponse)
+		return
+	}
 
 	err = bcrypt.CompareHashAndPassword([]byte(host.HostPass), []byte(authRequest.Password))
 	if err != nil {
@@ -485,7 +493,7 @@ func getNode(w http.ResponseWriter, r *http.Request) {
 		ServerConfig: server,
 		PeerIDs:      peerUpdate.PeerIDs,
 	}
-	if node.Proxy {
+	if host.ProxyEnabled {
 		proxyPayload, err := logic.GetPeersForProxy(&node, false)
 		if err == nil {
 			response.ProxyUpdate = proxyPayload
@@ -607,8 +615,10 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 	// consume password before hashing for mq client creation
 	nodePassword := data.Host.HostPass
 	data.Node.Server = servercfg.GetServer()
-	if _, err := logic.GetHost(data.Node.HostID.String()); err != nil {
-		if err := logic.CreateHost(&data.Host); err != nil {
+	if err := logic.CreateHost(&data.Host); err != nil {
+		if errors.Is(err, logic.ErrHostExists) {
+			logger.Log(3, "host exists .. no need to create")
+		} else {
 			logger.Log(0, "error creating host", err.Error())
 			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 			return
@@ -985,6 +995,12 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
+	host, err := logic.GetHost(node.HostID.String())
+	if err != nil {
+		logger.Log(0, "error retrieving host for node", node.ID.String(), err.Error())
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
 	if r.Header.Get("ismaster") != "yes" {
 		username := r.Header.Get("user")
 		if username != "" && !doesUserOwnNode(username, params["network"], nodeid) {
@@ -996,7 +1012,7 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete node"), "internal"))
 		return
 	}
-	if node.Proxy {
+	if host.ProxyEnabled {
 		mq.ProxyUpdate(&manager.ProxyManagerPayload{
 			Action:  manager.DeleteNetwork,
 			Network: node.Network,

+ 1 - 1
logic/gateway.go

@@ -46,7 +46,7 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
 	}
 	node.IsEgressGateway = true
 	node.EgressGatewayRanges = gateway.Ranges
-	node.EgressGatewayNatEnabled = gateway.NatEnabled == "yes"
+	node.EgressGatewayNatEnabled = models.ParseBool(gateway.NatEnabled)
 	node.EgressGatewayRequest = gateway // store entire request for use when preserving the egress gateway
 	postUpCmd := ""
 	postDownCmd := ""

+ 12 - 3
logic/hosts.go

@@ -2,13 +2,17 @@ package logic
 
 import (
 	"encoding/json"
-	"fmt"
+	"errors"
 
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/models"
+	"golang.org/x/crypto/bcrypt"
 )
 
+// ErrHostExists error indicating that host exists when trying to create new host
+var ErrHostExists error = errors.New("host already exists")
+
 // GetAllHosts - returns all hosts in flat list or error
 func GetAllHosts() ([]models.Host, error) {
 	currHostMap, err := GetHostsMap()
@@ -62,9 +66,14 @@ func GetHost(hostid string) (*models.Host, error) {
 func CreateHost(h *models.Host) error {
 	_, err := GetHost(h.ID.String())
 	if (err != nil && !database.IsEmptyRecord(err)) || (err == nil) {
-		return fmt.Errorf("host already exists")
+		return ErrHostExists
 	}
-
+	//encrypt that password so we never see it
+	hash, err := bcrypt.GenerateFromPassword([]byte(h.HostPass), 5)
+	if err != nil {
+		return err
+	}
+	h.HostPass = string(hash)
 	return UpsertHost(h)
 }
 

+ 10 - 8
logic/nodes.go

@@ -20,7 +20,6 @@ import (
 	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/servercfg"
 	"github.com/gravitl/netmaker/validation"
-	"golang.org/x/crypto/bcrypt"
 )
 
 const (
@@ -191,13 +190,6 @@ func CreateNode(node *models.Node) error {
 		return err
 	}
 
-	//encrypt that password so we never see it
-	hash, err := bcrypt.GenerateFromPassword([]byte(host.HostPass), 5)
-	if err != nil {
-		return err
-	}
-	//set password to encrypted password
-	host.HostPass = string(hash)
 	if !node.DNSOn {
 		if servercfg.IsDNSMode() {
 			node.DNSOn = true
@@ -225,6 +217,11 @@ func CreateNode(node *models.Node) error {
 			if node.Address.IP, err = UniqueAddress(node.Network, false); err != nil {
 				return err
 			}
+			_, cidr, err := net.ParseCIDR(parentNetwork.AddressRange)
+			if err != nil {
+				return err
+			}
+			node.Address.Mask = net.CIDRMask(cidr.Mask.Size())
 		}
 	} else if !IsIPUnique(node.Network, node.Address.String(), database.NODES_TABLE_NAME, false) {
 		return fmt.Errorf("invalid address: ipv4 " + node.Address.String() + " is not unique")
@@ -235,6 +232,11 @@ func CreateNode(node *models.Node) error {
 			if node.Address6.IP, err = UniqueAddress6(node.Network, false); err != nil {
 				return err
 			}
+			_, cidr, err := net.ParseCIDR(parentNetwork.AddressRange6)
+			if err != nil {
+				return err
+			}
+			node.Address6.Mask = net.CIDRMask(cidr.Mask.Size())
 		}
 	} else if !IsIPUnique(node.Network, node.Address6.String(), database.NODES_TABLE_NAME, true) {
 		return fmt.Errorf("invalid address: ipv6 " + node.Address6.String() + " is not unique")

+ 38 - 24
logic/peers.go

@@ -40,12 +40,16 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ProxyManagerPa
 	if !onlyPeers {
 		if node.IsRelayed {
 			relayNode := FindRelay(node)
+			relayHost, err := GetHost(relayNode.ID.String())
+			if err != nil {
+				return proxyPayload, err
+			}
 			if relayNode != nil {
 				host, err := GetHost(relayNode.HostID.String())
 				if err != nil {
 					logger.Log(0, "error retrieving host for relay node", relayNode.HostID.String(), err.Error())
 				}
-				relayEndpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayNode.EndpointIP, host.LocalListenPort))
+				relayEndpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayHost.EndpointIP, host.LocalListenPort))
 				if err != nil {
 					logger.Log(1, "failed to resolve relay node endpoint: ", err.Error())
 				}
@@ -74,7 +78,7 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ProxyManagerPa
 						if err != nil {
 							logger.Log(0, "error retrieving host for relayNode", relayedNode.ID.String(), err.Error())
 						}
-						relayedEndpoint, udpErr := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayedNode.EndpointIP, host.LocalListenPort))
+						relayedEndpoint, udpErr := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayedHost.EndpointIP, host.LocalListenPort))
 						if udpErr == nil {
 							relayPeersMap[host.PublicKey.String()] = proxy_models.RelayedConf{
 								RelayedPeerEndpoint: relayedEndpoint,
@@ -101,7 +105,7 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ProxyManagerPa
 		if err != nil {
 			continue
 		}
-		proxyStatus := peer.Proxy
+		proxyStatus := host.ProxyEnabled
 		listenPort := host.LocalListenPort
 		if proxyStatus {
 			listenPort = host.ProxyListenPort
@@ -113,9 +117,9 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ProxyManagerPa
 
 		}
 
-		endpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", peer.EndpointIP, listenPort))
+		endpoint, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", host.EndpointIP, listenPort))
 		if err != nil {
-			logger.Log(1, "failed to resolve udp addr for node: ", peer.ID.String(), peer.EndpointIP.String(), err.Error())
+			logger.Log(1, "failed to resolve udp addr for node: ", peer.ID.String(), host.EndpointIP.String(), err.Error())
 			continue
 		}
 		allowedips := GetAllowedIPs(node, &peer, nil, false)
@@ -145,7 +149,7 @@ func GetPeersForProxy(node *models.Node, onlyPeers bool) (manager.ProxyManagerPa
 					logger.Log(0, "error retrieving host for relayNode", relayNode.ID.String(), err.Error())
 					continue
 				}
-				relayTo, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayNode.EndpointIP, relayHost.LocalListenPort))
+				relayTo, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", relayHost.EndpointIP, relayHost.LocalListenPort))
 				if err == nil {
 					peerConfMap[host.PublicKey.String()] = proxy_models.PeerConf{
 
@@ -215,8 +219,11 @@ func GetPeerUpdate(node *models.Node) (models.PeerUpdate, error) {
 	if err != nil {
 		return models.PeerUpdate{}, err
 	}
-
-	if node.IsRelayed && !node.Proxy {
+	host, err := GetHost(node.ID.String())
+	if err != nil {
+		return peerUpdate, err
+	}
+	if node.IsRelayed && !host.ProxyEnabled {
 		return GetPeerUpdateForRelayedNode(node, udppeers)
 	}
 
@@ -224,6 +231,11 @@ func GetPeerUpdate(node *models.Node) (models.PeerUpdate, error) {
 	// #2 Set local address: set_local - could be a LOT BETTER and fix some bugs with additional logic
 	// #3 Set allowedips: set_allowedips
 	for _, peer := range currentPeers {
+		peerHost, err := GetHost(peer.ID.String())
+		if err != nil {
+			logger.Log(0, "error retrieving host for peer", node.ID.String(), err.Error())
+			return models.PeerUpdate{}, err
+		}
 		if peer.ID == node.ID {
 			//skip yourself
 			continue
@@ -237,7 +249,7 @@ func GetPeerUpdate(node *models.Node) (models.PeerUpdate, error) {
 		var setEndpoint = true
 
 		if peer.IsRelayed {
-			if !peer.Proxy && !(node.IsRelay && ncutils.StringSliceContains(node.RelayAddrs, peer.PrimaryAddress())) {
+			if !peerHost.ProxyEnabled && !(node.IsRelay && ncutils.StringSliceContains(node.RelayAddrs, peer.PrimaryAddress())) {
 				//skip -- will be added to relay
 				continue
 			} else if node.IsRelay && ncutils.StringSliceContains(node.RelayAddrs, peer.PrimaryAddress()) {
@@ -261,16 +273,11 @@ func GetPeerUpdate(node *models.Node) (models.PeerUpdate, error) {
 			logger.Log(0, "error retrieving host for node", node.ID.String(), err.Error())
 			return models.PeerUpdate{}, err
 		}
-		peerHost, err := GetHost(peer.HostID.String())
-		if err != nil {
-			logger.Log(0, "error retrieving host for peer", node.ID.String(), err.Error())
-			return models.PeerUpdate{}, err
-		}
-		if node.EndpointIP.String() == peer.EndpointIP.String() {
+		if host.EndpointIP.String() == peerHost.EndpointIP.String() {
 			//peer is on same network
 			// set_local
 			if host.LocalAddress.String() != peerHost.LocalAddress.String() && peerHost.LocalAddress.IP != nil {
-				peer.EndpointIP = peerHost.LocalAddress.IP
+				peerHost.EndpointIP = peerHost.LocalAddress.IP
 				if peerHost.LocalListenPort != 0 {
 					peerHost.ListenPort = peerHost.LocalListenPort
 				}
@@ -308,14 +315,14 @@ func GetPeerUpdate(node *models.Node) (models.PeerUpdate, error) {
 				peerHost.ListenPort = peerHost.LocalListenPort
 			}
 
-			endpoint := peer.EndpointIP.String() + ":" + strconv.FormatInt(int64(peerHost.ListenPort), 10)
+			endpoint := peerHost.EndpointIP.String() + ":" + strconv.FormatInt(int64(peerHost.ListenPort), 10)
 			address, err = net.ResolveUDPAddr("udp", endpoint)
 			if err != nil {
 				return models.PeerUpdate{}, err
 			}
 		}
 		fetchRelayedIps := true
-		if node.Proxy {
+		if host.ProxyEnabled {
 			fetchRelayedIps = false
 		}
 		allowedips := GetAllowedIPs(node, &peer, metrics, fetchRelayedIps)
@@ -741,7 +748,7 @@ func GetPeerUpdateForRelayedNode(node *models.Node, udppeers map[string]string)
 		listenPort = relayHost.LocalListenPort
 	}
 
-	endpoint := relay.EndpointIP.String() + ":" + strconv.FormatInt(int64(listenPort), 10)
+	endpoint := relayHost.EndpointIP.String() + ":" + strconv.FormatInt(int64(listenPort), 10)
 	address, err := net.ResolveUDPAddr("udp", endpoint)
 	if err != nil {
 		return models.PeerUpdate{}, err
@@ -781,6 +788,11 @@ func getEgressIPs(node, peer *models.Node) []net.IPNet {
 	if err != nil {
 		logger.Log(0, "error retrieving host for node", node.ID.String(), err.Error())
 	}
+	peerHost, err := GetHost(peer.ID.String())
+	if err != nil {
+		logger.Log(0, "error retrieving host for peer", peer.ID.String(), err.Error())
+	}
+
 	//check for internet gateway
 	internetGateway := false
 	if slices.Contains(peer.EgressGatewayRanges, "0.0.0.0/0") || slices.Contains(peer.EgressGatewayRanges, "::/0") {
@@ -793,9 +805,9 @@ func getEgressIPs(node, peer *models.Node) []net.IPNet {
 			logger.Log(1, "could not parse gateway IP range. Not adding ", iprange)
 			continue // if can't parse CIDR
 		}
-		nodeEndpointArr := strings.Split(peer.EndpointIP.String(), ":")          // getting the public ip of node
+		nodeEndpointArr := strings.Split(peerHost.EndpointIP.String(), ":")      // getting the public ip of node
 		if ipnet.Contains(net.ParseIP(nodeEndpointArr[0])) && !internetGateway { // ensuring egress gateway range does not contain endpoint of node
-			logger.Log(2, "egress IP range of ", iprange, " overlaps with ", node.EndpointIP.String(), ", omitting")
+			logger.Log(2, "egress IP range of ", iprange, " overlaps with ", host.EndpointIP.String(), ", omitting")
 			continue // skip adding egress range if overlaps with node's ip
 		}
 		// TODO: Could put in a lot of great logic to avoid conflicts / bad routes
@@ -814,11 +826,13 @@ func getEgressIPs(node, peer *models.Node) []net.IPNet {
 
 func getNodeAllowedIPs(peer, node *models.Node) []net.IPNet {
 	var allowedips = []net.IPNet{}
-
+	host, err := GetHost(node.ID.String())
+	if err != nil {
+		logger.Log(0, "error retrieving host for node", node.ID.String(), err.Error())
+	}
 	if peer.Address.IP != nil {
 		allowedips = append(allowedips, peer.Address)
 	}
-
 	if peer.Address6.IP != nil {
 		allowedips = append(allowedips, peer.Address6)
 	}
@@ -827,7 +841,7 @@ func getNodeAllowedIPs(peer, node *models.Node) []net.IPNet {
 
 		// parsing as a CIDR first. If valid CIDR, append
 		if _, ipnet, err := net.ParseCIDR(allowedIp); err == nil {
-			nodeEndpointArr := strings.Split(node.EndpointIP.String(), ":")
+			nodeEndpointArr := strings.Split(host.EndpointIP.String(), ":")
 			if !ipnet.Contains(net.IP(nodeEndpointArr[0])) && ipnet.IP.String() != peer.Address.IP.String() { // don't need to add an allowed ip that already exists..
 				allowedips = append(allowedips, *ipnet)
 			}

+ 18 - 0
models/host.go

@@ -41,3 +41,21 @@ type Host struct {
 	IsK8S            bool             `json:"isk8s" yaml:"isk8s"`
 	IsStatic         bool             `json:"isstatic" yaml:"isstatic"`
 }
+
+// FormatBool converts a boolean to a [yes|no] string
+func FormatBool(b bool) string {
+	s := "no"
+	if b {
+		s = "yes"
+	}
+	return s
+}
+
+// ParseBool parses a [yes|no] string to boolean value
+func ParseBool(s string) bool {
+	b := false
+	if s == "yes" {
+		b = true
+	}
+	return b
+}

+ 3 - 3
mq/handlers.go

@@ -57,9 +57,9 @@ func Ping(client mqtt.Client, msg mqtt.Message) {
 		node.SetLastCheckIn()
 		host.Version = checkin.Version
 		node.Connected = checkin.Connected
-		node.Interfaces = checkin.Ifaces
-		for i := range node.Interfaces {
-			node.Interfaces[i].AddressString = node.Interfaces[i].Address.String()
+		host.Interfaces = checkin.Ifaces
+		for i := range host.Interfaces {
+			host.Interfaces[i].AddressString = host.Interfaces[i].Address.String()
 		}
 		if err := logic.UpdateNode(&node, &node); err != nil {
 			logger.Log(0, "error updating node", node.ID.String(), " on checkin", err.Error())

+ 20 - 6
mq/publishers.go

@@ -49,12 +49,16 @@ func PublishProxyPeerUpdate(node *models.Node) error {
 
 // PublishSinglePeerUpdate --- determines and publishes a peer update to one node
 func PublishSinglePeerUpdate(node *models.Node) error {
+	host, err := logic.GetHost(node.ID.String())
+	if err != nil {
+		return nil
+	}
 
 	peerUpdate, err := logic.GetPeerUpdate(node)
 	if err != nil {
 		return err
 	}
-	if node.Proxy {
+	if host.ProxyEnabled {
 		proxyUpdate, err := logic.GetPeersForProxy(node, false)
 		if err != nil {
 			return err
@@ -73,7 +77,10 @@ func PublishSinglePeerUpdate(node *models.Node) error {
 
 // PublishPeerUpdate --- publishes a peer update to all the peers of a node
 func PublishExtPeerUpdate(node *models.Node) error {
-	var err error
+	host, err := logic.GetHost(node.ID.String())
+	if err != nil {
+		return nil
+	}
 	if !servercfg.IsMessageQueueBackend() {
 		return nil
 	}
@@ -85,7 +92,7 @@ func PublishExtPeerUpdate(node *models.Node) error {
 	if err != nil {
 		return err
 	}
-	if node.Proxy {
+	if host.ProxyEnabled {
 		proxyUpdate, err := logic.GetPeersForProxy(node, false)
 		if err == nil {
 			peerUpdate.ProxyUpdate = proxyUpdate
@@ -101,7 +108,10 @@ func PublishExtPeerUpdate(node *models.Node) error {
 
 // NodeUpdate -- publishes a node update
 func NodeUpdate(node *models.Node) error {
-	var err error
+	host, err := logic.GetHost(node.ID.String())
+	if err != nil {
+		return nil
+	}
 	if !servercfg.IsMessageQueueBackend() {
 		return nil
 	}
@@ -120,7 +130,7 @@ func NodeUpdate(node *models.Node) error {
 		logger.Log(2, "error publishing node update to peer ", node.ID.String(), err.Error())
 		return err
 	}
-	if node.Proxy {
+	if host.ProxyEnabled {
 		err = PublishProxyPeerUpdate(node)
 		if err != nil {
 			logger.Log(1, "failed to publish proxy update to node", node.ID.String(), "on network", node.Network, ":", err.Error())
@@ -132,7 +142,11 @@ func NodeUpdate(node *models.Node) error {
 
 // ProxyUpdate -- publishes updates to peers related to proxy
 func ProxyUpdate(proxyPayload *manager.ProxyManagerPayload, node *models.Node) error {
-	if !servercfg.IsMessageQueueBackend() || !node.Proxy {
+	host, err := logic.GetHost(node.ID.String())
+	if err != nil {
+		return nil
+	}
+	if !servercfg.IsMessageQueueBackend() || !host.ProxyEnabled {
 		return nil
 	}
 	logger.Log(3, "publishing proxy update to "+node.ID.String())