Browse Source

resolve merge conflicts from develop

abhishek9686 1 year ago
parent
commit
6778456105
16 changed files with 144 additions and 17 deletions
  1. 1 0
      .gitignore
  2. 2 2
      auth/auth.go
  3. 9 1
      auth/host_session.go
  4. 3 0
      cli/cmd/host/update.go
  5. 3 0
      cli/cmd/network/create.go
  6. 2 2
      go.mod
  7. 4 4
      go.sum
  8. 5 0
      logic/hosts.go
  9. 15 2
      logic/peers.go
  10. 7 0
      models/api_host.go
  11. 1 0
      models/host.go
  12. 1 1
      models/node.go
  13. 3 1
      mq/handlers.go
  14. 25 3
      pro/logic/nodes.go
  15. 1 1
      pro/logic/relays.go
  16. 62 0
      swagger.yml

+ 1 - 0
.gitignore

@@ -25,3 +25,4 @@ data/
 netmaker.exe
 netmaker.code-workspace
 dist/
+nmctl

+ 2 - 2
auth/auth.go

@@ -247,7 +247,7 @@ func addUser(email string) error {
 	} // generate random password to adapt to current model
 	var newPass, fetchErr = FetchPassValue("")
 	if fetchErr != nil {
-		logger.Log(0, "failed to get password: ", err.Error())
+		slog.Error("failed to get password", "error", err.Error())
 		return fetchErr
 	}
 	logger.Log(0, "fetched new pass: ", newPass, email)
@@ -266,7 +266,7 @@ func addUser(email string) error {
 		// TODO: add ability to add users with preemptive permissions
 		newUser.IsAdmin = false
 		if err = logic.CreateUser(&newUser); err != nil {
-			logger.Log(1, "error creating user,", email, "; user not added", "error", err.Error())
+			logger.Log(0, "error creating user,", email, "; user not added", "error", err.Error())
 		} else {
 			logger.Log(0, "user created from ", email)
 		}

+ 9 - 1
auth/host_session.go

@@ -248,12 +248,20 @@ func CheckNetRegAndHostUpdate(networks []string, h *models.Host, relayNodeId uui
 				// check if relay node exists and acting as relay
 				relaynode, err := logic.GetNodeByID(relayNodeId.String())
 				if err == nil && relaynode.IsRelay {
+					slog.Info(fmt.Sprintf("adding relayed node %s to relay %s on network %s", newNode.ID.String(), relayNodeId.String(), network))
 					newNode.IsRelayed = true
 					newNode.RelayedBy = relayNodeId.String()
-					slog.Info(fmt.Sprintf("adding relayed node %s to relay %s on network %s", newNode.ID.String(), relayNodeId.String(), network))
+					updatedRelayNode := relaynode
+					updatedRelayNode.RelayedNodes = append(updatedRelayNode.RelayedNodes, newNode.ID.String())
+					logic.UpdateRelayed(&relaynode, &updatedRelayNode)
+					if err := logic.UpsertNode(&updatedRelayNode); err != nil {
+						slog.Error("failed to update node", "nodeid", relayNodeId.String())
+					}
 					if err := logic.UpsertNode(newNode); err != nil {
 						slog.Error("failed to update node", "nodeid", relayNodeId.String())
 					}
+				} else {
+					slog.Error("failed to relay node. maybe specified relay node is actually not a relay?", "err", err)
 				}
 			}
 			logger.Log(1, "added new node", newNode.ID.String(), "to host", h.Name)

+ 3 - 0
cli/cmd/host/update.go

@@ -14,6 +14,7 @@ import (
 var (
 	apiHostFilePath string
 	endpoint        string
+	endpoint6       string
 	name            string
 	listenPort      int
 	mtu             int
@@ -40,6 +41,7 @@ var hostUpdateCmd = &cobra.Command{
 		} else {
 			apiHost.ID = args[0]
 			apiHost.EndpointIP = endpoint
+			apiHost.EndpointIPv6 = endpoint6
 			apiHost.Name = name
 			apiHost.ListenPort = listenPort
 			apiHost.MTU = mtu
@@ -54,6 +56,7 @@ var hostUpdateCmd = &cobra.Command{
 func init() {
 	hostUpdateCmd.Flags().StringVar(&apiHostFilePath, "file", "", "Path to host_definition.json")
 	hostUpdateCmd.Flags().StringVar(&endpoint, "endpoint", "", "Endpoint of the Host")
+	hostUpdateCmd.Flags().StringVar(&endpoint6, "endpoint6", "", "IPv6 Endpoint of the Host")
 	hostUpdateCmd.Flags().StringVar(&name, "name", "", "Host name")
 	hostUpdateCmd.Flags().IntVar(&listenPort, "listen_port", 0, "Listen port of the host")
 	hostUpdateCmd.Flags().IntVar(&mtu, "mtu", 0, "Host MTU size")

+ 3 - 0
cli/cmd/network/create.go

@@ -32,6 +32,9 @@ var networkCreateCmd = &cobra.Command{
 				network.AddressRange6 = address6
 				network.IsIPv6 = "yes"
 			}
+			if address == "" {
+				network.IsIPv4 = "no"
+			}
 			if udpHolePunch {
 				network.DefaultUDPHolePunch = "yes"
 			}

+ 2 - 2
go.mod

@@ -15,10 +15,10 @@ require (
 	github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
 	github.com/stretchr/testify v1.9.0
 	github.com/txn2/txeh v1.5.5
-	golang.org/x/crypto v0.21.0
+	golang.org/x/crypto v0.22.0
 	golang.org/x/net v0.22.0 // indirect
 	golang.org/x/oauth2 v0.18.0
-	golang.org/x/sys v0.18.0 // indirect
+	golang.org/x/sys v0.19.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
 	golang.zx2c4.com/wireguard/wgctrl v0.0.0-20221104135756-97bc4ad4a1cb
 	google.golang.org/protobuf v1.31.0 // indirect

+ 4 - 4
go.sum

@@ -101,8 +101,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
-golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
-golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
+golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
+golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -128,8 +128,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
-golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
+golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=

+ 5 - 0
logic/hosts.go

@@ -217,6 +217,7 @@ func UpdateHost(newHost, currentHost *models.Host) {
 	newHost.Nodes = currentHost.Nodes
 	newHost.PublicKey = currentHost.PublicKey
 	newHost.TrafficKeyPublic = currentHost.TrafficKeyPublic
+	newHost.EndpointIPv6 = currentHost.EndpointIPv6
 	// changeable fields
 	if len(newHost.Version) == 0 {
 		newHost.Version = currentHost.Version
@@ -258,6 +259,10 @@ func UpdateHostFromClient(newHost, currHost *models.Host) (sendPeerUpdate bool)
 		currHost.EndpointIP = newHost.EndpointIP
 		sendPeerUpdate = true
 	}
+	if currHost.EndpointIPv6.String() != newHost.EndpointIPv6.String() {
+		currHost.EndpointIPv6 = newHost.EndpointIPv6
+		sendPeerUpdate = true
+	}
 	currHost.DaemonInstalled = newHost.DaemonInstalled
 	currHost.Debug = newHost.Debug
 	currHost.Verbosity = newHost.Verbosity

+ 15 - 2
logic/peers.go

@@ -207,8 +207,21 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 					uselocal = false
 				}
 			}
+
+			//if host is ipv4 only or ipv4+ipv6, set the peer endpoint to ipv4 address, if host is ipv6 only, set the peer endpoint to ipv6 address
+			peerEndpoint := peerHost.EndpointIP
+			if ipv4 := host.EndpointIP.To4(); ipv4 != nil {
+				peerEndpoint = peerHost.EndpointIP
+			} else {
+				//if peer host's ipv6 address is empty, it means that peer is an IPv4 only host
+				//IPv4 only host could not communicate with IPv6 only host
+				if peerHost.EndpointIPv6 != nil && peerHost.EndpointIPv6.String() != "" {
+					peerEndpoint = peerHost.EndpointIPv6
+				}
+			}
+
 			peerConfig.Endpoint = &net.UDPAddr{
-				IP:   peerHost.EndpointIP,
+				IP:   peerEndpoint,
 				Port: GetPeerListenPort(peerHost),
 			}
 
@@ -372,6 +385,7 @@ func GetPeerListenPort(host *models.Host) int {
 // 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
+	allowedips = getNodeAllowedIPs(peer, node)
 	if peer.IsInternetGateway && node.InternetGwID == peer.ID.String() {
 		allowedips = append(allowedips, GetAllowedIpForInetNodeClient(node, peer)...)
 		return allowedips
@@ -382,7 +396,6 @@ func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet
 			return allowedips
 		}
 	}
-	allowedips = append(allowedips, getNodeAllowedIPs(peer, node)...)
 
 	// handle ingress gateway peers
 	if peer.IsIngressGateway {

+ 7 - 0
models/api_host.go

@@ -22,6 +22,7 @@ type ApiHost struct {
 	Interfaces          []ApiIface `json:"interfaces"            yaml:"interfaces"`
 	DefaultInterface    string     `json:"defaultinterface"      yaml:"defautlinterface"`
 	EndpointIP          string     `json:"endpointip"            yaml:"endpointip"`
+	EndpointIPv6        string     `json:"endpointipv6"            yaml:"endpointipv6"`
 	PublicKey           string     `json:"publickey"`
 	MacAddress          string     `json:"macaddress"`
 	Nodes               []string   `json:"nodes"`
@@ -43,6 +44,7 @@ func (h *Host) ConvertNMHostToAPI() *ApiHost {
 	a := ApiHost{}
 	a.Debug = h.Debug
 	a.EndpointIP = h.EndpointIP.String()
+	a.EndpointIPv6 = h.EndpointIPv6.String()
 	a.FirewallInUse = h.FirewallInUse
 	a.ID = h.ID.String()
 	a.Interfaces = make([]ApiIface, len(h.Interfaces))
@@ -83,6 +85,11 @@ func (a *ApiHost) ConvertAPIHostToNMHost(currentHost *Host) *Host {
 	} else {
 		h.EndpointIP = net.ParseIP(a.EndpointIP)
 	}
+	if len(a.EndpointIPv6) == 0 || strings.Contains(a.EndpointIPv6, "nil") {
+		h.EndpointIPv6 = currentHost.EndpointIPv6
+	} else {
+		h.EndpointIPv6 = net.ParseIP(a.EndpointIPv6)
+	}
 	h.Debug = a.Debug
 	h.FirewallInUse = a.FirewallInUse
 	h.IPForwarding = currentHost.IPForwarding

+ 1 - 0
models/host.go

@@ -63,6 +63,7 @@ type Host struct {
 	Interfaces          []Iface          `json:"interfaces"              yaml:"interfaces"`
 	DefaultInterface    string           `json:"defaultinterface"        yaml:"defaultinterface"`
 	EndpointIP          net.IP           `json:"endpointip"              yaml:"endpointip"`
+	EndpointIPv6        net.IP           `json:"endpointipv6"            yaml:"endpointipv6"`
 	IsDocker            bool             `json:"isdocker"                yaml:"isdocker"`
 	IsK8S               bool             `json:"isk8s"                   yaml:"isk8s"`
 	IsStatic            bool             `json:"isstatic"                yaml:"isstatic"`

+ 1 - 1
models/node.go

@@ -205,7 +205,7 @@ func (extPeer *ExtClient) AddressIPNet4() net.IPNet {
 // ExtClient.AddressIPNet6 - return ipv6 IPNet format
 func (extPeer *ExtClient) AddressIPNet6() net.IPNet {
 	return net.IPNet{
-		IP:   net.ParseIP(extPeer.Address),
+		IP:   net.ParseIP(extPeer.Address6),
 		Mask: net.CIDRMask(128, 128),
 	}
 }

+ 3 - 1
mq/handlers.go

@@ -282,9 +282,11 @@ func HandleHostCheckin(h, currentHost *models.Host) bool {
 		!h.EndpointIP.Equal(currentHost.EndpointIP) ||
 		(len(h.NatType) > 0 && h.NatType != currentHost.NatType) ||
 		h.DefaultInterface != currentHost.DefaultInterface ||
-		(h.ListenPort != 0 && h.ListenPort != currentHost.ListenPort) || (h.WgPublicListenPort != 0 && h.WgPublicListenPort != currentHost.WgPublicListenPort)
+		(h.ListenPort != 0 && h.ListenPort != currentHost.ListenPort) ||
+		(h.WgPublicListenPort != 0 && h.WgPublicListenPort != currentHost.WgPublicListenPort) || (!h.EndpointIPv6.Equal(currentHost.EndpointIPv6))
 	if ifaceDelta { // only save if something changes
 		currentHost.EndpointIP = h.EndpointIP
+		currentHost.EndpointIPv6 = h.EndpointIPv6
 		currentHost.Interfaces = h.Interfaces
 		currentHost.DefaultInterface = h.DefaultInterface
 		currentHost.NatType = h.NatType

+ 25 - 3
pro/logic/nodes.go

@@ -10,6 +10,11 @@ import (
 	"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 {
@@ -104,6 +109,9 @@ func SetDefaultGwForRelayedUpdate(relayed, relay models.Node, peerUpdate models.
 	if relay.InternetGwID != "" {
 		peerUpdate.ChangeDefaultGw = true
 		peerUpdate.DefaultGwIp = relay.Address.IP
+		if peerUpdate.DefaultGwIp == nil {
+			peerUpdate.DefaultGwIp = relay.Address6.IP
+		}
 
 	}
 	return peerUpdate
@@ -118,7 +126,9 @@ func SetDefaultGw(node models.Node, peerUpdate models.HostPeerUpdate) models.Hos
 		}
 		peerUpdate.ChangeDefaultGw = true
 		peerUpdate.DefaultGwIp = inetNode.Address.IP
-
+		if peerUpdate.DefaultGwIp == nil {
+			peerUpdate.DefaultGwIp = inetNode.Address6.IP
+		}
 	}
 	return peerUpdate
 }
@@ -140,6 +150,18 @@ func GetNetworkIngresses(network string) ([]models.Node, error) {
 
 // GetAllowedIpsForInet - get inet cidr for node using a inet gw
 func GetAllowedIpForInetNodeClient(node, peer *models.Node) []net.IPNet {
-	_, ipnet, _ := net.ParseCIDR("0.0.0.0/0")
-	return []net.IPNet{*ipnet}
+	var allowedips = []net.IPNet{}
+
+	if peer.Address.IP != nil {
+		_, ipnet, _ := net.ParseCIDR(IPv4Network)
+		allowedips = append(allowedips, *ipnet)
+		return allowedips
+	}
+
+	if peer.Address6.IP != nil {
+		_, ipnet, _ := net.ParseCIDR(IPv6Network)
+		allowedips = append(allowedips, *ipnet)
+	}
+
+	return allowedips
 }

+ 1 - 1
pro/logic/relays.go

@@ -238,7 +238,7 @@ func getRelayedAddresses(id string) []net.IPNet {
 		addrs = append(addrs, node.Address)
 	}
 	if node.Address6.IP != nil {
-		node.Address.Mask = net.CIDRMask(128, 128)
+		node.Address6.Mask = net.CIDRMask(128, 128)
 		addrs = append(addrs, node.Address6)
 	}
 	return addrs

+ 62 - 0
swagger.yml

@@ -642,6 +642,9 @@ definitions:
                     $ref: '#/definitions/EgressNetworkRoutes'
                 type: array
                 x-go-name: EgressRoutes
+            endpoint_detection:
+                type: boolean
+                x-go-name: EndpointDetection
             fw_update:
                 $ref: '#/definitions/FwUpdate'
             host:
@@ -1203,6 +1206,8 @@ definitions:
                 type: string
             APIPort:
                 type: string
+            AllowedEmailDomains:
+                type: string
             AllowedOrigin:
                 type: string
             AuthProvider:
@@ -1324,6 +1329,9 @@ definitions:
                 type: integer
             Version:
                 type: string
+            endpoint_detection:
+                type: boolean
+                x-go-name: EndpointDetection
         type: object
         x-go-package: github.com/gravitl/netmaker/config
     Signal:
@@ -1584,6 +1592,17 @@ paths:
             summary: Push DNS entries to nameserver.
             tags:
                 - dns
+    /api/emqx/hosts:
+        delete:
+            operationId: delEmqxHosts
+            responses:
+                "200":
+                    $ref: '#/responses/apiHostResponse'
+            schemes:
+                - https
+            summary: Lists all hosts.
+            tags:
+                - hosts
     /api/extclients:
         get:
             operationId: getAllExtClients
@@ -2654,6 +2673,49 @@ paths:
             summary: Transfers superadmin role to an admin user.
             tags:
                 - user
+    /api/users_pending:
+        get:
+            operationId: getPendingUsers
+            responses:
+                "200":
+                    $ref: '#/responses/userBodyResponse'
+            schemes:
+                - https
+            summary: Get all pending users.
+            tags:
+                - user
+    /api/users_pending/{username}/pending:
+        delete:
+            operationId: deleteAllPendingUsers
+            responses:
+                "200":
+                    $ref: '#/responses/userBodyResponse'
+            schemes:
+                - https
+            summary: delete all pending users.
+            tags:
+                - user
+    /api/users_pending/user/{username}:
+        delete:
+            operationId: deletePendingUser
+            responses:
+                "200":
+                    $ref: '#/responses/userBodyResponse'
+            schemes:
+                - https
+            summary: delete pending user.
+            tags:
+                - user
+        post:
+            operationId: approvePendingUser
+            responses:
+                "200":
+                    $ref: '#/responses/userBodyResponse'
+            schemes:
+                - https
+            summary: approve pending user.
+            tags:
+                - user
     /api/v1/enrollment-keys:
         get:
             operationId: getEnrollmentKeys