Skip to content

Commit 657a24e

Browse files
authored
Merge pull request #3527 from gravitl/NET-2075
2 parents 1d92a0a + 4e2b799 commit 657a24e

File tree

17 files changed

+304
-220
lines changed

17 files changed

+304
-220
lines changed

auth/host_session.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,10 @@ func CheckNetRegAndHostUpdate(networks []string, h *models.Host, relayNodeId uui
289289
logic.CreateFailOver(*newNode)
290290
// make host remote access gateway
291291
logic.CreateIngressGateway(network, newNode.ID.String(), models.IngressRequest{})
292+
logic.CreateRelay(models.RelayRequest{
293+
NodeID: newNode.ID.String(),
294+
NetID: network,
295+
})
292296
}
293297
}
294298
}

controllers/gateway.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ func createGateway(w http.ResponseWriter, r *http.Request) {
5050
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
5151
return
5252
}
53+
if req.IsInternetGateway && len(req.InetNodeClientIDs) > 0 {
54+
err = logic.ValidateInetGwReq(node, req.InetNodeReq, false)
55+
if err != nil {
56+
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
57+
return
58+
}
59+
}
60+
5361
node, err = logic.CreateIngressGateway(netid, nodeid, req.IngressRequest)
5462
if err != nil {
5563
logger.Log(0, r.Header.Get("user"),
@@ -84,6 +92,22 @@ func createGateway(w http.ResponseWriter, r *http.Request) {
8492

8593
}
8694
}
95+
if len(req.InetNodeClientIDs) > 0 {
96+
logic.SetInternetGw(&node, req.InetNodeReq)
97+
if servercfg.IsPro {
98+
if _, exists := logic.FailOverExists(node.Network); exists {
99+
go func() {
100+
logic.ResetFailedOverPeer(&node)
101+
mq.PublishPeerUpdate(false)
102+
}()
103+
}
104+
}
105+
if node.IsGw && node.IngressDNS == "" {
106+
node.IngressDNS = "1.1.1.1"
107+
}
108+
logic.UpsertNode(&node)
109+
}
110+
87111
logger.Log(
88112
1,
89113
r.Header.Get("user"),
@@ -164,6 +188,7 @@ func deleteGateway(w http.ResponseWriter, r *http.Request) {
164188
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
165189
return
166190
}
191+
logic.UnsetInternetGw(&node)
167192
node.IsGw = false
168193
logic.UpsertNode(&node)
169194
logger.Log(1, r.Header.Get("user"), "deleted gw", nodeid, "on network", netid)

controllers/hosts.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,10 @@ func addHostToNetwork(w http.ResponseWriter, r *http.Request) {
522522
logic.CreateFailOver(*newNode)
523523
// make host remote access gateway
524524
logic.CreateIngressGateway(network, newNode.ID.String(), models.IngressRequest{})
525+
logic.CreateRelay(models.RelayRequest{
526+
NodeID: newNode.ID.String(),
527+
NetID: network,
528+
})
525529
}
526530
go func() {
527531
mq.HostUpdate(&models.HostUpdate{

pro/controllers/inet_gws.go renamed to controllers/inet_gws.go

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package controllers
1+
package controller
22

33
import (
44
"encoding/json"
@@ -10,20 +10,9 @@ import (
1010
"github.com/gravitl/netmaker/logic"
1111
"github.com/gravitl/netmaker/models"
1212
"github.com/gravitl/netmaker/mq"
13-
proLogic "github.com/gravitl/netmaker/pro/logic"
1413
"github.com/gravitl/netmaker/servercfg"
1514
)
1615

17-
// InetHandlers - handlers for internet gw
18-
func InetHandlers(r *mux.Router) {
19-
r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(createInternetGw))).
20-
Methods(http.MethodPost)
21-
r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(updateInternetGw))).
22-
Methods(http.MethodPut)
23-
r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(deleteInternetGw))).
24-
Methods(http.MethodDelete)
25-
}
26-
2716
// @Summary Create an internet gateway
2817
// @Router /api/nodes/{network}/{nodeid}/inet_gw [post]
2918
// @Tags PRO
@@ -70,16 +59,16 @@ func createInternetGw(w http.ResponseWriter, r *http.Request) {
7059
)
7160
return
7261
}
73-
err = proLogic.ValidateInetGwReq(node, request, false)
62+
err = logic.ValidateInetGwReq(node, request, false)
7463
if err != nil {
7564
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
7665
return
7766
}
7867
logic.SetInternetGw(&node, request)
7968
if servercfg.IsPro {
80-
if _, exists := proLogic.FailOverExists(node.Network); exists {
69+
if _, exists := logic.FailOverExists(node.Network); exists {
8170
go func() {
82-
proLogic.ResetFailedOverPeer(&node)
71+
logic.ResetFailedOverPeer(&node)
8372
mq.PublishPeerUpdate(false)
8473
}()
8574
}
@@ -140,7 +129,7 @@ func updateInternetGw(w http.ResponseWriter, r *http.Request) {
140129
)
141130
return
142131
}
143-
err = proLogic.ValidateInetGwReq(node, request, true)
132+
err = logic.ValidateInetGwReq(node, request, true)
144133
if err != nil {
145134
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
146135
return

controllers/legacy.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ import (
1111
func legacyHandlers(r *mux.Router) {
1212
r.HandleFunc("/api/v1/legacy/nodes", logic.SecurityCheck(true, http.HandlerFunc(wipeLegacyNodes))).
1313
Methods(http.MethodDelete)
14+
r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(createInternetGw))).
15+
Methods(http.MethodPost)
16+
r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(updateInternetGw))).
17+
Methods(http.MethodPut)
18+
r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(deleteInternetGw))).
19+
Methods(http.MethodDelete)
1420
}
1521

1622
// @Summary Delete all legacy nodes from DB.

controllers/node.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,7 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
626626
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
627627
return
628628
}
629+
629630
if !servercfg.IsPro {
630631
newData.AdditionalRagIps = []string{}
631632
}
@@ -638,6 +639,13 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
638639
)
639640
return
640641
}
642+
if newNode.IsInternetGateway && len(newNode.InetNodeReq.InetNodeClientIDs) > 0 {
643+
err = logic.ValidateInetGwReq(*newNode, newNode.InetNodeReq, newNode.IsInternetGateway && currentNode.IsInternetGateway)
644+
if err != nil {
645+
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
646+
return
647+
}
648+
}
641649
relayUpdate := logic.RelayUpdates(&currentNode, newNode)
642650
if relayUpdate && newNode.IsRelay {
643651
err = logic.ValidateRelay(models.RelayRequest{
@@ -657,7 +665,6 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
657665
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
658666
return
659667
}
660-
ifaceDelta := logic.IfaceDelta(&currentNode, newNode)
661668
aclUpdate := currentNode.DefaultACL != newNode.DefaultACL
662669

663670
err = logic.UpdateNode(&currentNode, newNode)
@@ -670,7 +677,17 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
670677
if relayUpdate {
671678
logic.UpdateRelayed(&currentNode, newNode)
672679
}
673-
680+
if !currentNode.IsInternetGateway && newNode.IsInternetGateway {
681+
logic.SetInternetGw(newNode, newNode.InetNodeReq)
682+
}
683+
if currentNode.IsInternetGateway && newNode.IsInternetGateway {
684+
logic.UnsetInternetGw(newNode)
685+
logic.SetInternetGw(newNode, newNode.InetNodeReq)
686+
}
687+
if !newNode.IsInternetGateway {
688+
logic.UnsetInternetGw(newNode)
689+
}
690+
logic.UpsertNode(newNode)
674691
logic.GetNodeStatus(newNode, false)
675692

676693
apiNode := newNode.ConvertToAPINode()
@@ -707,11 +724,6 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
707724
if err := mq.NodeUpdate(newNode); err != nil {
708725
slog.Error("error publishing node update to node", "node", newNode.ID, "error", err)
709726
}
710-
if aclUpdate || relayupdate || ifaceDelta {
711-
if err := mq.PublishPeerUpdate(false); err != nil {
712-
logger.Log(0, "error during node ACL update for node", newNode.ID.String())
713-
}
714-
}
715727
mq.PublishPeerUpdate(false)
716728
if servercfg.IsDNSMode() {
717729
logic.SetDNS()

logic/acls.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ var MigrateToGws = func() {
294294
return
295295
}
296296
for _, node := range nodes {
297-
if node.IsIngressGateway || node.IsRelay {
297+
if node.IsIngressGateway || node.IsRelay || node.IsInternetGateway {
298298
node.IsGw = true
299299
node.IsIngressGateway = true
300300
node.IsRelay = true

logic/gateway.go

Lines changed: 162 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@ package logic
33
import (
44
"errors"
55
"fmt"
6+
"net"
67
"slices"
78
"sort"
89
"time"
910

11+
"github.com/google/uuid"
1012
"github.com/gravitl/netmaker/database"
1113
"github.com/gravitl/netmaker/logger"
1214
"github.com/gravitl/netmaker/models"
1315
"github.com/gravitl/netmaker/servercfg"
16+
"golang.org/x/exp/slog"
17+
)
18+
19+
var (
20+
IPv4Network = "0.0.0.0/0"
21+
IPv6Network = "::/0"
1422
)
1523

1624
// IsInternetGw - checks if node is acting as internet gw
@@ -267,9 +275,6 @@ func DeleteIngressGateway(nodeid string) (models.Node, []models.ExtClient, error
267275
logger.Log(3, "deleting ingress gateway")
268276
node.LastModified = time.Now().UTC()
269277
node.IsIngressGateway = false
270-
if !servercfg.IsPro {
271-
node.IsInternetGateway = false
272-
}
273278
delete(node.Tags, models.TagID(fmt.Sprintf("%s.%s", node.Network, models.GwTagName)))
274279
node.IngressGatewayRange = ""
275280
node.Metadata = ""
@@ -316,3 +321,157 @@ func IsUserAllowedAccessToExtClient(username string, client models.ExtClient) bo
316321
}
317322
return true
318323
}
324+
325+
func ValidateInetGwReq(inetNode models.Node, req models.InetNodeReq, update bool) error {
326+
inetHost, err := GetHost(inetNode.HostID.String())
327+
if err != nil {
328+
return err
329+
}
330+
if inetHost.FirewallInUse == models.FIREWALL_NONE {
331+
return errors.New("iptables or nftables needs to be installed")
332+
}
333+
if inetNode.InternetGwID != "" {
334+
return fmt.Errorf("node %s is using a internet gateway already", inetHost.Name)
335+
}
336+
if inetNode.IsRelayed {
337+
return fmt.Errorf("node %s is being relayed", inetHost.Name)
338+
}
339+
340+
for _, clientNodeID := range req.InetNodeClientIDs {
341+
clientNode, err := GetNodeByID(clientNodeID)
342+
if err != nil {
343+
return err
344+
}
345+
if clientNode.IsFailOver {
346+
return errors.New("failover node cannot be set to use internet gateway")
347+
}
348+
clientHost, err := GetHost(clientNode.HostID.String())
349+
if err != nil {
350+
return err
351+
}
352+
if clientHost.IsDefault {
353+
return errors.New("default host cannot be set to use internet gateway")
354+
}
355+
if clientHost.OS != models.OS_Types.Linux && clientHost.OS != models.OS_Types.Windows {
356+
return errors.New("can only attach linux or windows machine to a internet gateway")
357+
}
358+
if clientNode.IsInternetGateway {
359+
return fmt.Errorf("node %s acting as internet gateway cannot use another internet gateway", clientHost.Name)
360+
}
361+
if update {
362+
if clientNode.InternetGwID != "" && clientNode.InternetGwID != inetNode.ID.String() {
363+
return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
364+
}
365+
} else {
366+
if clientNode.InternetGwID != "" {
367+
return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
368+
}
369+
}
370+
if clientNode.FailedOverBy != uuid.Nil {
371+
ResetFailedOverPeer(&clientNode)
372+
}
373+
374+
if clientNode.IsRelayed && clientNode.RelayedBy != inetNode.ID.String() {
375+
return fmt.Errorf("node %s is being relayed", clientHost.Name)
376+
}
377+
378+
for _, nodeID := range clientHost.Nodes {
379+
node, err := GetNodeByID(nodeID)
380+
if err != nil {
381+
continue
382+
}
383+
if node.InternetGwID != "" && node.InternetGwID != inetNode.ID.String() {
384+
return errors.New("nodes on same host cannot use different internet gateway")
385+
}
386+
387+
}
388+
}
389+
return nil
390+
}
391+
392+
// SetInternetGw - sets the node as internet gw based on flag bool
393+
func SetInternetGw(node *models.Node, req models.InetNodeReq) {
394+
node.IsInternetGateway = true
395+
node.InetNodeReq = req
396+
for _, clientNodeID := range req.InetNodeClientIDs {
397+
clientNode, err := GetNodeByID(clientNodeID)
398+
if err != nil {
399+
continue
400+
}
401+
clientNode.InternetGwID = node.ID.String()
402+
UpsertNode(&clientNode)
403+
}
404+
405+
}
406+
407+
func UnsetInternetGw(node *models.Node) {
408+
nodes, err := GetNetworkNodes(node.Network)
409+
if err != nil {
410+
slog.Error("failed to get network nodes", "network", node.Network, "error", err)
411+
return
412+
}
413+
for _, clientNode := range nodes {
414+
if node.ID.String() == clientNode.InternetGwID {
415+
clientNode.InternetGwID = ""
416+
UpsertNode(&clientNode)
417+
}
418+
419+
}
420+
node.IsInternetGateway = false
421+
node.InetNodeReq = models.InetNodeReq{}
422+
423+
}
424+
425+
func SetDefaultGwForRelayedUpdate(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
426+
if relay.InternetGwID != "" {
427+
relayedHost, err := GetHost(relayed.HostID.String())
428+
if err != nil {
429+
return peerUpdate
430+
}
431+
peerUpdate.ChangeDefaultGw = true
432+
peerUpdate.DefaultGwIp = relay.Address.IP
433+
if peerUpdate.DefaultGwIp == nil || relayedHost.EndpointIP == nil {
434+
peerUpdate.DefaultGwIp = relay.Address6.IP
435+
}
436+
437+
}
438+
return peerUpdate
439+
}
440+
441+
func SetDefaultGw(node models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
442+
if node.InternetGwID != "" {
443+
444+
inetNode, err := GetNodeByID(node.InternetGwID)
445+
if err != nil {
446+
return peerUpdate
447+
}
448+
host, err := GetHost(node.HostID.String())
449+
if err != nil {
450+
return peerUpdate
451+
}
452+
453+
peerUpdate.ChangeDefaultGw = true
454+
peerUpdate.DefaultGwIp = inetNode.Address.IP
455+
if peerUpdate.DefaultGwIp == nil || host.EndpointIP == nil {
456+
peerUpdate.DefaultGwIp = inetNode.Address6.IP
457+
}
458+
}
459+
return peerUpdate
460+
}
461+
462+
// GetAllowedIpForInetNodeClient - get inet cidr for node using a inet gw
463+
func GetAllowedIpForInetNodeClient(node, peer *models.Node) []net.IPNet {
464+
var allowedips = []net.IPNet{}
465+
466+
if peer.Address.IP != nil {
467+
_, ipnet, _ := net.ParseCIDR(IPv4Network)
468+
allowedips = append(allowedips, *ipnet)
469+
}
470+
471+
if peer.Address6.IP != nil {
472+
_, ipnet, _ := net.ParseCIDR(IPv6Network)
473+
allowedips = append(allowedips, *ipnet)
474+
}
475+
476+
return allowedips
477+
}

0 commit comments

Comments
 (0)