abhishek9686 1 rok pred
rodič
commit
4961625188

+ 13 - 26
controllers/node.go

@@ -345,7 +345,7 @@ func getNode(w http.ResponseWriter, r *http.Request) {
 	var params = mux.Vars(r)
 	nodeid := params["nodeid"]
 
-	node, err := validateParams(nodeid, params["network"])
+	node, err := logic.ValidateParams(nodeid, params["network"])
 	if err != nil {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
@@ -402,9 +402,9 @@ func getNode(w http.ResponseWriter, r *http.Request) {
 func createEgressGateway(w http.ResponseWriter, r *http.Request) {
 	var gateway models.EgressGatewayRequest
 	var params = mux.Vars(r)
-	node, err := validateParams(params["nodeid"], params["network"])
+	node, err := logic.ValidateParams(params["nodeid"], params["network"])
 	if err != nil {
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
 	w.Header().Set("Content-Type", "application/json")
@@ -453,9 +453,9 @@ func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
 	var params = mux.Vars(r)
 	nodeid := params["nodeid"]
 	netid := params["network"]
-	node, err := validateParams(nodeid, netid)
+	node, err := logic.ValidateParams(nodeid, netid)
 	if err != nil {
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
 	node, err = logic.DeleteEgressGateway(netid, nodeid)
@@ -497,9 +497,9 @@ func createIngressGateway(w http.ResponseWriter, r *http.Request) {
 	w.Header().Set("Content-Type", "application/json")
 	nodeid := params["nodeid"]
 	netid := params["network"]
-	node, err := validateParams(nodeid, netid)
+	node, err := logic.ValidateParams(nodeid, netid)
 	if err != nil {
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
 	var request models.IngressRequest
@@ -540,9 +540,9 @@ func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
 	var params = mux.Vars(r)
 	nodeid := params["nodeid"]
 	netid := params["network"]
-	node, err := validateParams(nodeid, netid)
+	node, err := logic.ValidateParams(nodeid, netid)
 	if err != nil {
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
 	node, removedClients, err := logic.DeleteIngressGateway(nodeid)
@@ -618,9 +618,9 @@ func updateNode(w http.ResponseWriter, r *http.Request) {
 
 	//start here
 	nodeid := params["nodeid"]
-	currentNode, err := validateParams(nodeid, params["network"])
+	currentNode, err := logic.ValidateParams(nodeid, params["network"])
 	if err != nil {
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
 	var newData models.ApiNode
@@ -695,9 +695,9 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
 	// get params
 	var params = mux.Vars(r)
 	var nodeid = params["nodeid"]
-	node, err := validateParams(nodeid, params["network"])
+	node, err := logic.ValidateParams(nodeid, params["network"])
 	if err != nil {
-		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "bad request"))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
 	forceDelete := r.URL.Query().Get("force") == "true"
@@ -716,16 +716,3 @@ func deleteNode(w http.ResponseWriter, r *http.Request) {
 	logger.Log(1, r.Header.Get("user"), "Deleted node", nodeid, "from network", params["network"])
 	go mq.PublishMqUpdatesForDeletedNode(node, !fromNode, gwClients)
 }
-
-func validateParams(nodeid, netid string) (models.Node, error) {
-	node, err := logic.GetNodeByID(nodeid)
-	if err != nil {
-		slog.Error("error fetching node", "node", nodeid, "error", err.Error())
-		return node, fmt.Errorf("error fetching node during parameter validation: %v", err)
-	}
-	if node.Network != netid {
-		slog.Error("network url param does not match node id", "url nodeid", netid, "node", node.Network)
-		return node, fmt.Errorf("network url param does not match node network")
-	}
-	return node, nil
-}

+ 5 - 10
logic/gateway.go

@@ -9,15 +9,10 @@ import (
 	"github.com/gravitl/netmaker/models"
 )
 
-var (
-	// SetInternetGw - sets the node as internet gw based on flag bool
-	SetInternetGw = func(node *models.Node, flag bool) {
-	}
-	// IsInternetGw - checks if node is acting as internet gw
-	IsInternetGw = func(node models.Node) bool {
-		return false
-	}
-)
+// IsInternetGw - checks if node is acting as internet gw
+func IsInternetGw(node models.Node) bool {
+	return node.IsInternetGateway
+}
 
 // GetInternetGateways - gets all the nodes that are internet gateways
 func GetInternetGateways() ([]models.Node, error) {
@@ -170,7 +165,7 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq
 		return models.Node{}, err
 	}
 	node.IsIngressGateway = true
-	SetInternetGw(&node, ingress.IsInternetGateway)
+	node.IsInternetGateway = ingress.IsInternetGateway
 	node.IngressGatewayRange = network.AddressRange
 	node.IngressGatewayRange6 = network.AddressRange6
 	node.IngressDNS = ingress.ExtclientDNS

+ 13 - 0
logic/nodes.go

@@ -598,3 +598,16 @@ func SortApiNodes(unsortedNodes []models.ApiNode) {
 		return unsortedNodes[i].ID < unsortedNodes[j].ID
 	})
 }
+
+func ValidateParams(nodeid, netid string) (models.Node, error) {
+	node, err := GetNodeByID(nodeid)
+	if err != nil {
+		slog.Error("error fetching node", "node", nodeid, "error", err.Error())
+		return node, fmt.Errorf("error fetching node during parameter validation: %v", err)
+	}
+	if node.Network != netid {
+		slog.Error("network url param does not match node id", "url nodeid", netid, "node", node.Network)
+		return node, fmt.Errorf("network url param does not match node network")
+	}
+	return node, nil
+}

+ 8 - 6
models/node.go

@@ -66,7 +66,6 @@ type CommonNode struct {
 	IsEgressGateway     bool      `json:"isegressgateway" yaml:"isegressgateway"`
 	EgressGatewayRanges []string  `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
 	IsIngressGateway    bool      `json:"isingressgateway" yaml:"isingressgateway"`
-	IsInternetGateway   bool      `json:"isinternetgateway" yaml:"isinternetgateway"`
 	IsRelayed           bool      `json:"isrelayed" bson:"isrelayed" yaml:"isrelayed"`
 	RelayedBy           string    `json:"relayedby" bson:"relayedby" yaml:"relayedby"`
 	IsRelay             bool      `json:"isrelay" bson:"isrelay" yaml:"isrelay"`
@@ -89,11 +88,14 @@ type Node struct {
 	IngressGatewayRange6    string               `json:"ingressgatewayrange6" bson:"ingressgatewayrange6" yaml:"ingressgatewayrange6"`
 	Metadata                string               `json:"metadata"`
 	// == PRO ==
-	DefaultACL    string              `json:"defaultacl,omitempty" bson:"defaultacl,omitempty" yaml:"defaultacl,omitempty" validate:"checkyesornoorunset"`
-	OwnerID       string              `json:"ownerid,omitempty" bson:"ownerid,omitempty" yaml:"ownerid,omitempty"`
-	IsFailOver    bool                `json:"is_fail_over" yaml:"is_fail_over"`
-	FailOverPeers map[string]struct{} `json:"fail_over_peers" yaml:"fail_over_peers"`
-	FailedOverBy  uuid.UUID           `json:"failed_over_by" yaml:"failed_over_by"`
+	DefaultACL        string              `json:"defaultacl,omitempty" bson:"defaultacl,omitempty" yaml:"defaultacl,omitempty" validate:"checkyesornoorunset"`
+	OwnerID           string              `json:"ownerid,omitempty" bson:"ownerid,omitempty" yaml:"ownerid,omitempty"`
+	IsFailOver        bool                `json:"is_fail_over" yaml:"is_fail_over"`
+	FailOverPeers     map[string]struct{} `json:"fail_over_peers" yaml:"fail_over_peers"`
+	FailedOverBy      uuid.UUID           `json:"failed_over_by" yaml:"failed_over_by"`
+	IsInternetGateway bool                `json:"isinternetgateway" yaml:"isinternetgateway"`
+	InetNodeReq       InetNodeReq         `json:"inet_node_req" yaml:"inet_node_req"`
+	InternetGwID      string              `json:"internetgw_node_id" yaml:"internetgw_node_id"`
 }
 
 // LegacyNode - legacy struct for node model

+ 5 - 0
models/structs.go

@@ -196,6 +196,11 @@ type IngressRequest struct {
 	IsInternetGateway bool   `json:"is_internet_gw"`
 }
 
+// InetNodeReq - exit node request struct
+type InetNodeReq struct {
+	InetNodeClientIDs []string `json:"inet_node_client_id"`
+}
+
 // ServerUpdateData - contains data to configure server
 // and if it should set peers
 type ServerUpdateData struct {

+ 155 - 0
pro/controllers/inet_gws.go

@@ -0,0 +1,155 @@
+package controllers
+
+import (
+	"encoding/json"
+	"errors"
+	"net/http"
+
+	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/logger"
+	"github.com/gravitl/netmaker/logic"
+	"github.com/gravitl/netmaker/models"
+	"github.com/gravitl/netmaker/mq"
+	proLogic "github.com/gravitl/netmaker/pro/logic"
+)
+
+// InetHandlers - handlers for internet gw
+func InetHandlers(r *mux.Router) {
+	r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(createInternetGw))).Methods(http.MethodPost)
+	r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(updateInternetGw))).Methods(http.MethodPut)
+	r.HandleFunc("/api/nodes/{network}/{nodeid}/inet_gw", logic.SecurityCheck(true, http.HandlerFunc(deleteInternetGw))).Methods(http.MethodDelete)
+}
+
+// swagger:route POST /api/nodes/{network}/{nodeid}/inet_gw nodes createInternetGw
+//
+// Create an inet node.
+//
+//			Schemes: https
+//
+//			Security:
+//	  		oauth
+//
+//			Responses:
+//				200: nodeResponse
+func createInternetGw(w http.ResponseWriter, r *http.Request) {
+	var params = mux.Vars(r)
+	w.Header().Set("Content-Type", "application/json")
+	nodeid := params["nodeid"]
+	netid := params["network"]
+	node, err := logic.ValidateParams(nodeid, netid)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	if node.IsInternetGateway {
+		logic.ReturnSuccessResponse(w, r, "node is already acting as internet gateway")
+		return
+	}
+	var request models.InetNodeReq
+	err = json.NewDecoder(r.Body).Decode(&request)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	err = proLogic.ValidateInetGwReq(request)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	proLogic.SetInternetGw(&node, request)
+	err = logic.UpsertNode(&node)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+	apiNode := node.ConvertToAPINode()
+	logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid)
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(apiNode)
+	go mq.PublishPeerUpdate(false)
+}
+
+// swagger:route PUT /api/nodes/{network}/{nodeid}/inet_gw nodes updateInternetGw
+//
+// update an inet node.
+//
+//			Schemes: https
+//
+//			Security:
+//	  		oauth
+//
+//			Responses:
+//				200: nodeResponse
+func updateInternetGw(w http.ResponseWriter, r *http.Request) {
+	var params = mux.Vars(r)
+	w.Header().Set("Content-Type", "application/json")
+	nodeid := params["nodeid"]
+	netid := params["network"]
+	node, err := logic.ValidateParams(nodeid, netid)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	var request models.InetNodeReq
+	err = json.NewDecoder(r.Body).Decode(&request)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	if !node.IsInternetGateway {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node is not a internet gw"), "badrequest"))
+		return
+	}
+	err = proLogic.ValidateInetGwReq(request)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	proLogic.UnsetInternetGw(&node)
+	proLogic.SetInternetGw(&node, request)
+	err = logic.UpsertNode(&node)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+	apiNode := node.ConvertToAPINode()
+	logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid)
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(apiNode)
+	go mq.PublishPeerUpdate(false)
+}
+
+// swagger:route DELETE /api/nodes/{network}/{nodeid}/inet_gw nodes deleteInternetGw
+//
+// Delete an internet gw.
+//
+//			Schemes: https
+//
+//			Security:
+//	  		oauth
+//
+//			Responses:
+//				200: nodeResponse
+func deleteInternetGw(w http.ResponseWriter, r *http.Request) {
+	var params = mux.Vars(r)
+	w.Header().Set("Content-Type", "application/json")
+	nodeid := params["nodeid"]
+	netid := params["network"]
+	node, err := logic.ValidateParams(nodeid, netid)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+
+	proLogic.UnsetInternetGw(&node)
+	err = logic.UpsertNode(&node)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+	apiNode := node.ConvertToAPINode()
+	logger.Log(1, r.Header.Get("user"), "created ingress gateway on node", nodeid, "on network", netid)
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(apiNode)
+	go mq.PublishPeerUpdate(false)
+}

+ 0 - 2
pro/initialize.go

@@ -100,8 +100,6 @@ func InitPro() {
 	logic.UpdateRelayed = proLogic.UpdateRelayed
 	logic.SetRelayedNodes = proLogic.SetRelayedNodes
 	logic.RelayUpdates = proLogic.RelayUpdates
-	logic.IsInternetGw = proLogic.IsInternetGw
-	logic.SetInternetGw = proLogic.SetInternetGw
 	logic.GetTrialEndDate = getTrialEndDate
 	mq.UpdateMetrics = proLogic.MQUpdateMetrics
 	mq.UpdateMetricsFallBack = proLogic.MQUpdateMetricsFallBack

+ 44 - 7
pro/logic/nodes.go

@@ -1,24 +1,61 @@
 package logic
 
 import (
-	celogic "github.com/gravitl/netmaker/logic"
+	"errors"
+
+	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
 )
 
-// IsInternetGw - checks if node is acting as internet gw
-func IsInternetGw(node models.Node) bool {
-	return node.IsInternetGateway
+func ValidateInetGwReq(req models.InetNodeReq) error {
+	for _, clientNodeID := range req.InetNodeClientIDs {
+		clientNode, err := logic.GetNodeByID(clientNodeID)
+		if err != nil {
+			continue
+		}
+		if clientNode.IsInternetGateway {
+			return errors.New("node acting as internet gateway cannot use another internet gateway")
+		}
+	}
+	return nil
 }
 
 // SetInternetGw - sets the node as internet gw based on flag bool
-func SetInternetGw(node *models.Node, flag bool) {
-	node.IsInternetGateway = flag
+func SetInternetGw(node *models.Node, req models.InetNodeReq) {
+	node.IsInternetGateway = true
+	node.InetNodeReq = req
+	for _, clientNodeID := range req.InetNodeClientIDs {
+		clientNode, err := logic.GetNodeByID(clientNodeID)
+		if err != nil {
+			continue
+		}
+		clientNode.InternetGwID = node.ID.String()
+		logic.UpsertNode(&clientNode)
+	}
+
+}
+
+func UnsetInternetGw(node *models.Node) {
+	for _, nodeID := range node.InetNodeReq.InetNodeClientIDs {
+		clientNode, err := logic.GetNodeByID(nodeID)
+		if err != nil {
+			continue
+		}
+		if node.ID.String() == clientNode.InternetGwID {
+			node.InternetGwID = ""
+			logic.UpsertNode(node)
+		}
+
+	}
+	node.IsInternetGateway = false
+	node.InetNodeReq = models.InetNodeReq{}
+
 }
 
 // GetNetworkIngresses - gets the gateways of a network
 func GetNetworkIngresses(network string) ([]models.Node, error) {
 	var ingresses []models.Node
-	netNodes, err := celogic.GetNetworkNodes(network)
+	netNodes, err := logic.GetNetworkNodes(network)
 	if err != nil {
 		return []models.Node{}, err
 	}