mirror of
https://github.com/gravitl/netmaker.git
synced 2025-09-07 21:54:54 +08:00
NET-1914: add gw apis, move relays into CE (#3309)
* add gw apis, move relays into CE * set gw field on relay and ingress creation * add gw handlers to relay and ingress apis * if node is inetgw and gw add dns * remove pro check on relays * fetch node before updating
This commit is contained in:
parent
6509da9b61
commit
8297642b90
14 changed files with 485 additions and 556 deletions
|
@ -24,6 +24,7 @@ var HttpMiddlewares = []mux.MiddlewareFunc{
|
|||
// HttpHandlers - handler functions for REST interactions
|
||||
var HttpHandlers = []interface{}{
|
||||
nodeHandlers,
|
||||
gwHandlers,
|
||||
userHandlers,
|
||||
networkHandlers,
|
||||
dnsHandlers,
|
||||
|
|
207
controllers/gateway.go
Normal file
207
controllers/gateway.go
Normal file
|
@ -0,0 +1,207 @@
|
|||
package controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.org/x/exp/slog"
|
||||
)
|
||||
|
||||
func gwHandlers(r *mux.Router) {
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/gateway", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceIngress, http.HandlerFunc(createGateway)))).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/gateway", logic.SecurityCheck(true, http.HandlerFunc(deleteGateway))).Methods(http.MethodDelete)
|
||||
// old relay handlers
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/createrelay", logic.SecurityCheck(true, http.HandlerFunc(createGateway))).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/deleterelay", logic.SecurityCheck(true, http.HandlerFunc(deleteGateway))).Methods(http.MethodDelete)
|
||||
}
|
||||
|
||||
// @Summary Create a gateway
|
||||
// @Router /api/nodes/{network}/{nodeid}/gateway [post]
|
||||
// @Tags Nodes
|
||||
// @Security oauth2
|
||||
// @Success 200 {object} models.ApiNode
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func createGateway(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var params = mux.Vars(r)
|
||||
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 req models.CreateGwReq
|
||||
err = json.NewDecoder(r.Body).Decode(&req)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
node, err = logic.CreateIngressGateway(netid, nodeid, req.IngressRequest)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"),
|
||||
fmt.Sprintf("failed to create gateway on node [%s] on network [%s]: %v",
|
||||
nodeid, netid, err))
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
req.RelayRequest.NetID = netid
|
||||
req.RelayRequest.NodeID = nodeid
|
||||
_, relayNode, err := logic.CreateRelay(req.RelayRequest)
|
||||
if err != nil {
|
||||
logger.Log(
|
||||
0,
|
||||
r.Header.Get("user"),
|
||||
fmt.Sprintf(
|
||||
"failed to create relay on node [%s] on network [%s]: %v",
|
||||
req.RelayRequest.NodeID,
|
||||
req.RelayRequest.NetID,
|
||||
err,
|
||||
),
|
||||
)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
for _, relayedNodeID := range relayNode.RelayedNodes {
|
||||
relayedNode, err := logic.GetNodeByID(relayedNodeID)
|
||||
if err == nil {
|
||||
if relayedNode.FailedOverBy != uuid.Nil {
|
||||
go logic.ResetFailedOverPeer(&relayedNode)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
logger.Log(
|
||||
1,
|
||||
r.Header.Get("user"),
|
||||
"created gw node",
|
||||
req.RelayRequest.NodeID,
|
||||
"on network",
|
||||
req.RelayRequest.NetID,
|
||||
)
|
||||
apiNode := relayNode.ConvertToAPINode()
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(apiNode)
|
||||
go func() {
|
||||
if err := mq.NodeUpdate(&node); err != nil {
|
||||
slog.Error("error publishing node update to node", "node", node.ID, "error", err)
|
||||
}
|
||||
mq.PublishPeerUpdate(false)
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
// @Summary Delete a gateway
|
||||
// @Router /api/nodes/{network}/{nodeid}/gateway [delete]
|
||||
// @Tags Nodes
|
||||
// @Security oauth2
|
||||
// @Success 200 {object} models.ApiNode
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func deleteGateway(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var params = mux.Vars(r)
|
||||
nodeid := params["nodeid"]
|
||||
netid := params["network"]
|
||||
node, err := logic.ValidateParams(nodeid, netid)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
node, removedClients, err := logic.DeleteIngressGateway(nodeid)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"),
|
||||
fmt.Sprintf("failed to delete ingress gateway on node [%s] on network [%s]: %v",
|
||||
nodeid, netid, err))
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
updateNodes, node, err := logic.DeleteRelay(netid, nodeid)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
node, err = logic.GetNodeByID(node.ID.String())
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "failed to get node", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
node.IsGw = false
|
||||
logic.UpsertNode(&node)
|
||||
logger.Log(1, r.Header.Get("user"), "deleted gw", nodeid, "on network", netid)
|
||||
|
||||
go func() {
|
||||
host, err := logic.GetHost(node.HostID.String())
|
||||
if err == nil {
|
||||
allNodes, err := logic.GetAllNodes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, relayedNode := range updateNodes {
|
||||
err = mq.NodeUpdate(&relayedNode)
|
||||
if err != nil {
|
||||
logger.Log(
|
||||
1,
|
||||
"relayed node update ",
|
||||
relayedNode.ID.String(),
|
||||
"on network",
|
||||
relayedNode.Network,
|
||||
": ",
|
||||
err.Error(),
|
||||
)
|
||||
|
||||
}
|
||||
h, err := logic.GetHost(relayedNode.HostID.String())
|
||||
if err == nil {
|
||||
if h.OS == models.OS_Types.IoT {
|
||||
nodes, err := logic.GetAllNodes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
node.IsRelay = true // for iot update to recognise that it has to delete relay peer
|
||||
if err = mq.PublishSingleHostPeerUpdate(h, nodes, &node, nil, false, nil); err != nil {
|
||||
logger.Log(1, "failed to publish peer update to host", h.ID.String(), ": ", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(removedClients) > 0 {
|
||||
if err := mq.PublishSingleHostPeerUpdate(host, allNodes, nil, removedClients[:], false, nil); err != nil {
|
||||
slog.Error("publishSingleHostUpdate", "host", host.Name, "error", err)
|
||||
}
|
||||
}
|
||||
mq.PublishPeerUpdate(false)
|
||||
if err := mq.NodeUpdate(&node); err != nil {
|
||||
slog.Error(
|
||||
"error publishing node update to node",
|
||||
"node",
|
||||
node.ID,
|
||||
"error",
|
||||
err,
|
||||
)
|
||||
}
|
||||
if servercfg.IsDNSMode() {
|
||||
logic.SetDNS()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
apiNode := node.ConvertToAPINode()
|
||||
logger.Log(1, r.Header.Get("user"), "deleted ingress gateway", nodeid)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(apiNode)
|
||||
}
|
|
@ -28,8 +28,8 @@ func nodeHandlers(r *mux.Router) {
|
|||
r.HandleFunc("/api/nodes/{network}/{nodeid}", Authorize(true, true, "node", http.HandlerFunc(deleteNode))).Methods(http.MethodDelete)
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/creategateway", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceEgress, http.HandlerFunc(createEgressGateway)))).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/deletegateway", logic.SecurityCheck(true, http.HandlerFunc(deleteEgressGateway))).Methods(http.MethodDelete)
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/createingress", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceIngress, http.HandlerFunc(createIngressGateway)))).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/deleteingress", logic.SecurityCheck(true, http.HandlerFunc(deleteIngressGateway))).Methods(http.MethodDelete)
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/createingress", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceIngress, http.HandlerFunc(createGateway)))).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/deleteingress", logic.SecurityCheck(true, http.HandlerFunc(deleteGateway))).Methods(http.MethodDelete)
|
||||
r.HandleFunc("/api/nodes/adm/{network}/authenticate", authenticate).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/v1/nodes/migrate", migrate).Methods(http.MethodPost)
|
||||
}
|
||||
|
@ -548,113 +548,6 @@ func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
|
|||
}()
|
||||
}
|
||||
|
||||
// == INGRESS ==
|
||||
|
||||
// @Summary Create an remote access gateway
|
||||
// @Router /api/nodes/{network}/{nodeid}/createingress [post]
|
||||
// @Tags Nodes
|
||||
// @Security oauth2
|
||||
// @Success 200 {object} models.ApiNode
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func createIngressGateway(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.IngressRequest
|
||||
json.NewDecoder(r.Body).Decode(&request)
|
||||
node, err = logic.CreateIngressGateway(netid, nodeid, request)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"),
|
||||
fmt.Sprintf("failed to create ingress gateway on node [%s] on network [%s]: %v",
|
||||
nodeid, netid, err))
|
||||
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 func() {
|
||||
if err := mq.NodeUpdate(&node); err != nil {
|
||||
slog.Error("error publishing node update to node", "node", node.ID, "error", err)
|
||||
}
|
||||
mq.PublishPeerUpdate(false)
|
||||
}()
|
||||
}
|
||||
|
||||
// @Summary Delete an remote access gateway
|
||||
// @Router /api/nodes/{network}/{nodeid}/deleteingress [delete]
|
||||
// @Tags Nodes
|
||||
// @Security oauth2
|
||||
// @Success 200 {object} models.ApiNode
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func deleteIngressGateway(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var params = mux.Vars(r)
|
||||
nodeid := params["nodeid"]
|
||||
netid := params["network"]
|
||||
node, err := logic.ValidateParams(nodeid, netid)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
node, removedClients, err := logic.DeleteIngressGateway(nodeid)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"),
|
||||
fmt.Sprintf("failed to delete ingress gateway on node [%s] on network [%s]: %v",
|
||||
nodeid, netid, err))
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
|
||||
apiNode := node.ConvertToAPINode()
|
||||
logger.Log(1, r.Header.Get("user"), "deleted ingress gateway", nodeid)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(apiNode)
|
||||
|
||||
if len(removedClients) > 0 {
|
||||
host, err := logic.GetHost(node.HostID.String())
|
||||
if err == nil {
|
||||
allNodes, err := logic.GetAllNodes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
if err := mq.PublishSingleHostPeerUpdate(host, allNodes, nil, removedClients[:], false, nil); err != nil {
|
||||
slog.Error("publishSingleHostUpdate", "host", host.Name, "error", err)
|
||||
}
|
||||
mq.PublishPeerUpdate(false)
|
||||
if err := mq.NodeUpdate(&node); err != nil {
|
||||
slog.Error(
|
||||
"error publishing node update to node",
|
||||
"node",
|
||||
node.ID,
|
||||
"error",
|
||||
err,
|
||||
)
|
||||
}
|
||||
if servercfg.IsDNSMode() {
|
||||
logic.SetDNS()
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @Summary Update an individual node
|
||||
// @Router /api/nodes/{network}/{nodeid} [put]
|
||||
// @Tags Nodes
|
||||
|
|
|
@ -141,14 +141,14 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq
|
|||
return models.Node{}, err
|
||||
}
|
||||
if node.IsRelayed {
|
||||
return models.Node{}, errors.New("ingress cannot be created on a relayed node")
|
||||
return models.Node{}, errors.New("gateway cannot be created on a relayed node")
|
||||
}
|
||||
host, err := GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
return models.Node{}, err
|
||||
}
|
||||
if host.OS != "linux" {
|
||||
return models.Node{}, errors.New("ingress can only be created on linux based node")
|
||||
return models.Node{}, errors.New("gateway can only be created on linux based node")
|
||||
}
|
||||
|
||||
network, err := GetParentNetwork(netid)
|
||||
|
@ -156,12 +156,16 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq
|
|||
return models.Node{}, err
|
||||
}
|
||||
node.IsIngressGateway = true
|
||||
node.IsGw = true
|
||||
if !servercfg.IsPro {
|
||||
node.IsInternetGateway = ingress.IsInternetGateway
|
||||
}
|
||||
node.IngressGatewayRange = network.AddressRange
|
||||
node.IngressGatewayRange6 = network.AddressRange6
|
||||
node.IngressDNS = ingress.ExtclientDNS
|
||||
if node.IsInternetGateway && node.IngressDNS == "" {
|
||||
node.IngressDNS = "1.1.1.1"
|
||||
}
|
||||
node.IngressPersistentKeepalive = 20
|
||||
if ingress.PersistentKeepalive != 0 {
|
||||
node.IngressPersistentKeepalive = ingress.PersistentKeepalive
|
||||
|
|
|
@ -222,21 +222,19 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
|
|||
hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(node)...)
|
||||
}
|
||||
_, isFailOverPeer := node.FailOverPeers[peer.ID.String()]
|
||||
if servercfg.IsPro {
|
||||
if (node.IsRelayed && node.RelayedBy != peer.ID.String()) ||
|
||||
(peer.IsRelayed && peer.RelayedBy != node.ID.String()) || isFailOverPeer {
|
||||
// if node is relayed and peer is not the relay, set remove to true
|
||||
if _, ok := peerIndexMap[peerHost.PublicKey.String()]; ok {
|
||||
continue
|
||||
}
|
||||
peerConfig.Remove = true
|
||||
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
|
||||
peerIndexMap[peerHost.PublicKey.String()] = len(hostPeerUpdate.Peers) - 1
|
||||
if (node.IsRelayed && node.RelayedBy != peer.ID.String()) ||
|
||||
(peer.IsRelayed && peer.RelayedBy != node.ID.String()) || isFailOverPeer {
|
||||
// if node is relayed and peer is not the relay, set remove to true
|
||||
if _, ok := peerIndexMap[peerHost.PublicKey.String()]; ok {
|
||||
continue
|
||||
}
|
||||
if node.IsRelayed && node.RelayedBy == peer.ID.String() {
|
||||
hostPeerUpdate = SetDefaultGwForRelayedUpdate(node, peer, hostPeerUpdate)
|
||||
}
|
||||
peerConfig.Remove = true
|
||||
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
|
||||
peerIndexMap[peerHost.PublicKey.String()] = len(hostPeerUpdate.Peers) - 1
|
||||
continue
|
||||
}
|
||||
if node.IsRelayed && node.RelayedBy == peer.ID.String() {
|
||||
hostPeerUpdate = SetDefaultGwForRelayedUpdate(node, peer, hostPeerUpdate)
|
||||
}
|
||||
|
||||
uselocal := false
|
||||
|
|
0
logic/pro/failover
Normal file
0
logic/pro/failover
Normal file
238
logic/relay.go
238
logic/relay.go
|
@ -1,34 +1,246 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic/acls/nodeacls"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
)
|
||||
|
||||
var GetRelays = func() ([]models.Node, error) {
|
||||
return []models.Node{}, nil
|
||||
// GetRelays - gets all the nodes that are relays
|
||||
func GetRelays() ([]models.Node, error) {
|
||||
nodes, err := GetAllNodes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
relays := make([]models.Node, 0)
|
||||
for _, node := range nodes {
|
||||
if node.IsRelay {
|
||||
relays = append(relays, node)
|
||||
}
|
||||
}
|
||||
return relays, nil
|
||||
}
|
||||
|
||||
var RelayedAllowedIPs = func(peer, node *models.Node) []net.IPNet {
|
||||
return []net.IPNet{}
|
||||
// CreateRelay - creates a relay
|
||||
func CreateRelay(relay models.RelayRequest) ([]models.Node, models.Node, error) {
|
||||
var returnnodes []models.Node
|
||||
|
||||
node, err := GetNodeByID(relay.NodeID)
|
||||
if err != nil {
|
||||
return returnnodes, models.Node{}, err
|
||||
}
|
||||
host, err := GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
return returnnodes, models.Node{}, err
|
||||
}
|
||||
if host.OS != "linux" {
|
||||
return returnnodes, models.Node{}, fmt.Errorf("only linux machines can be gateway nodes")
|
||||
}
|
||||
err = ValidateRelay(relay, false)
|
||||
if err != nil {
|
||||
return returnnodes, models.Node{}, err
|
||||
}
|
||||
node.IsRelay = true
|
||||
node.IsGw = true
|
||||
node.RelayedNodes = relay.RelayedNodes
|
||||
node.SetLastModified()
|
||||
err = UpsertNode(&node)
|
||||
if err != nil {
|
||||
return returnnodes, node, err
|
||||
}
|
||||
returnnodes = SetRelayedNodes(true, relay.NodeID, relay.RelayedNodes)
|
||||
return returnnodes, node, nil
|
||||
}
|
||||
|
||||
var GetAllowedIpsForRelayed = func(relayed, relay *models.Node) []net.IPNet {
|
||||
return []net.IPNet{}
|
||||
// SetRelayedNodes- sets and saves node as relayed
|
||||
func SetRelayedNodes(setRelayed bool, relay string, relayed []string) []models.Node {
|
||||
var returnnodes []models.Node
|
||||
for _, id := range relayed {
|
||||
node, err := GetNodeByID(id)
|
||||
if err != nil {
|
||||
logger.Log(0, "setRelayedNodes.GetNodebyID", err.Error())
|
||||
continue
|
||||
}
|
||||
node.IsRelayed = setRelayed
|
||||
if setRelayed {
|
||||
node.RelayedBy = relay
|
||||
} else {
|
||||
node.RelayedBy = ""
|
||||
}
|
||||
node.SetLastModified()
|
||||
if err := UpsertNode(&node); err != nil {
|
||||
logger.Log(0, "setRelayedNodes.Insert", err.Error())
|
||||
continue
|
||||
}
|
||||
returnnodes = append(returnnodes, node)
|
||||
}
|
||||
return returnnodes
|
||||
}
|
||||
|
||||
var UpdateRelayed = func(currentNode, newNode *models.Node) {
|
||||
// func GetRelayedNodes(relayNode *models.Node) (models.Node, error) {
|
||||
// var returnnodes []models.Node
|
||||
// networkNodes, err := GetNetworkNodes(relayNode.Network)
|
||||
// if err != nil {
|
||||
// return returnnodes, err
|
||||
// }
|
||||
// for _, node := range networkNodes {
|
||||
// for _, addr := range relayNode.RelayAddrs {
|
||||
// if addr == node.Address.IP.String() || addr == node.Address6.IP.String() {
|
||||
// returnnodes = append(returnnodes, node)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return returnnodes, nil
|
||||
// }
|
||||
|
||||
// ValidateRelay - checks if relay is valid
|
||||
func ValidateRelay(relay models.RelayRequest, update bool) error {
|
||||
var err error
|
||||
|
||||
node, err := GetNodeByID(relay.NodeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !update && node.IsRelay {
|
||||
return errors.New("node is already acting as a relay")
|
||||
}
|
||||
for _, relayedNodeID := range relay.RelayedNodes {
|
||||
relayedNode, err := GetNodeByID(relayedNodeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if relayedNode.IsIngressGateway {
|
||||
return errors.New("cannot relay an ingress gateway (" + relayedNodeID + ")")
|
||||
}
|
||||
if relayedNode.IsInternetGateway {
|
||||
return errors.New("cannot relay an internet gateway (" + relayedNodeID + ")")
|
||||
}
|
||||
if relayedNode.InternetGwID != "" && relayedNode.InternetGwID != relay.NodeID {
|
||||
return errors.New("cannot relay an internet client (" + relayedNodeID + ")")
|
||||
}
|
||||
if relayedNode.IsFailOver {
|
||||
return errors.New("cannot relay a failOver (" + relayedNodeID + ")")
|
||||
}
|
||||
if relayedNode.FailedOverBy != uuid.Nil {
|
||||
ResetFailedOverPeer(&relayedNode)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var SetRelayedNodes = func(setRelayed bool, relay string, relayed []string) []models.Node {
|
||||
return []models.Node{}
|
||||
// UpdateRelayNodes - updates relay nodes
|
||||
func updateRelayNodes(relay string, oldNodes []string, newNodes []string) []models.Node {
|
||||
_ = SetRelayedNodes(false, relay, oldNodes)
|
||||
return SetRelayedNodes(true, relay, newNodes)
|
||||
}
|
||||
|
||||
var RelayUpdates = func(currentNode, newNode *models.Node) bool {
|
||||
return false
|
||||
func RelayUpdates(currentNode, newNode *models.Node) bool {
|
||||
relayUpdates := false
|
||||
if newNode.IsRelay {
|
||||
if len(newNode.RelayedNodes) != len(currentNode.RelayedNodes) {
|
||||
relayUpdates = true
|
||||
} else {
|
||||
for i, node := range newNode.RelayedNodes {
|
||||
if node != currentNode.RelayedNodes[i] {
|
||||
relayUpdates = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return relayUpdates
|
||||
}
|
||||
|
||||
var ValidateRelay = func(relay models.RelayRequest, update bool) error {
|
||||
return nil
|
||||
// UpdateRelayed - updates a relay's relayed nodes, and sends updates to the relayed nodes over MQ
|
||||
func UpdateRelayed(currentNode, newNode *models.Node) {
|
||||
updatenodes := updateRelayNodes(currentNode.ID.String(), currentNode.RelayedNodes, newNode.RelayedNodes)
|
||||
if len(updatenodes) > 0 {
|
||||
for _, relayedNode := range updatenodes {
|
||||
node := relayedNode
|
||||
ResetFailedOverPeer(&node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteRelay - deletes a relay
|
||||
func DeleteRelay(network, nodeid string) ([]models.Node, models.Node, error) {
|
||||
var returnnodes []models.Node
|
||||
node, err := GetNodeByID(nodeid)
|
||||
if err != nil {
|
||||
return returnnodes, models.Node{}, err
|
||||
}
|
||||
returnnodes = SetRelayedNodes(false, nodeid, node.RelayedNodes)
|
||||
node.IsRelay = false
|
||||
node.RelayedNodes = []string{}
|
||||
node.SetLastModified()
|
||||
if err = UpsertNode(&node); err != nil {
|
||||
return returnnodes, models.Node{}, err
|
||||
}
|
||||
return returnnodes, node, nil
|
||||
}
|
||||
|
||||
func RelayedAllowedIPs(peer, node *models.Node) []net.IPNet {
|
||||
var allowedIPs = []net.IPNet{}
|
||||
for _, relayedNodeID := range peer.RelayedNodes {
|
||||
if node.ID.String() == relayedNodeID {
|
||||
continue
|
||||
}
|
||||
relayedNode, err := GetNodeByID(relayedNodeID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
allowed := getRelayedAddresses(relayedNodeID)
|
||||
if relayedNode.IsEgressGateway {
|
||||
allowed = append(allowed, GetEgressIPs(&relayedNode)...)
|
||||
}
|
||||
allowedIPs = append(allowedIPs, allowed...)
|
||||
}
|
||||
return allowedIPs
|
||||
}
|
||||
|
||||
// GetAllowedIpsForRelayed - returns the peerConfig for a node relayed by relay
|
||||
func GetAllowedIpsForRelayed(relayed, relay *models.Node) (allowedIPs []net.IPNet) {
|
||||
if relayed.RelayedBy != relay.ID.String() {
|
||||
logger.Log(0, "RelayedByRelay called with invalid parameters")
|
||||
return
|
||||
}
|
||||
if relay.InternetGwID != "" {
|
||||
return GetAllowedIpForInetNodeClient(relayed, relay)
|
||||
}
|
||||
peers, err := GetNetworkNodes(relay.Network)
|
||||
if err != nil {
|
||||
logger.Log(0, "error getting network clients", err.Error())
|
||||
return
|
||||
}
|
||||
for _, peer := range peers {
|
||||
if peer.ID == relayed.ID || peer.ID == relay.ID {
|
||||
continue
|
||||
}
|
||||
if nodeacls.AreNodesAllowed(nodeacls.NetworkID(relayed.Network), nodeacls.NodeID(relayed.ID.String()), nodeacls.NodeID(peer.ID.String())) {
|
||||
allowedIPs = append(allowedIPs, GetAllowedIPs(relayed, &peer, nil)...)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getRelayedAddresses(id string) []net.IPNet {
|
||||
addrs := []net.IPNet{}
|
||||
node, err := GetNodeByID(id)
|
||||
if err != nil {
|
||||
logger.Log(0, "getRelayedAddresses: "+err.Error())
|
||||
return addrs
|
||||
}
|
||||
if node.Address.IP != nil {
|
||||
node.Address.Mask = net.CIDRMask(32, 32)
|
||||
addrs = append(addrs, node.Address)
|
||||
}
|
||||
if node.Address6.IP != nil {
|
||||
node.Address6.Mask = net.CIDRMask(128, 128)
|
||||
addrs = append(addrs, node.Address6)
|
||||
}
|
||||
return addrs
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ func Run() {
|
|||
updateHosts()
|
||||
updateNodes()
|
||||
updateAcls()
|
||||
migrateToGws()
|
||||
}
|
||||
|
||||
func assignSuperAdmin() {
|
||||
|
@ -441,3 +442,18 @@ func createDefaultTagsAndPolicies() {
|
|||
}
|
||||
logic.MigrateAclPolicies()
|
||||
}
|
||||
|
||||
func migrateToGws() {
|
||||
nodes, err := logic.GetAllNodes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, node := range nodes {
|
||||
if node.IsIngressGateway || node.IsRelay {
|
||||
node.IsGw = true
|
||||
node.IsIngressGateway = true
|
||||
node.IsRelay = true
|
||||
logic.UpsertNode(&node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
9
models/gateway.go
Normal file
9
models/gateway.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
package models
|
||||
|
||||
type CreateGwReq struct {
|
||||
IngressRequest
|
||||
RelayRequest
|
||||
}
|
||||
|
||||
type DeleteGw struct {
|
||||
}
|
|
@ -78,11 +78,12 @@ type CommonNode struct {
|
|||
Action string `json:"action" yaml:"action"`
|
||||
LocalAddress net.IPNet `json:"localaddress" yaml:"localaddress"`
|
||||
IsEgressGateway bool `json:"isegressgateway" yaml:"isegressgateway"`
|
||||
EgressGatewayRanges []string `json:"egressgatewayranges" yaml:"egressgatewayranges" bson:"egressgatewayranges"`
|
||||
EgressGatewayRanges []string `json:"egressgatewayranges" yaml:"egressgatewayranges"`
|
||||
IsIngressGateway bool `json:"isingressgateway" yaml:"isingressgateway"`
|
||||
IsRelayed bool `json:"isrelayed" yaml:"isrelayed" bson:"isrelayed"`
|
||||
RelayedBy string `json:"relayedby" yaml:"relayedby" bson:"relayedby"`
|
||||
IsRelay bool `json:"isrelay" yaml:"isrelay" bson:"isrelay"`
|
||||
IsRelayed bool `json:"isrelayed" yaml:"isrelayed"`
|
||||
RelayedBy string `json:"relayedby" yaml:"relayedby"`
|
||||
IsRelay bool `json:"isrelay" yaml:"isrelay"`
|
||||
IsGw bool `json:"is_gw" yaml:"is_gw"`
|
||||
RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"`
|
||||
IngressDNS string `json:"ingressdns" yaml:"ingressdns"`
|
||||
DNSOn bool `json:"dnson" yaml:"dnson"`
|
||||
|
|
|
@ -84,6 +84,9 @@ func createInternetGw(w http.ResponseWriter, r *http.Request) {
|
|||
}()
|
||||
}
|
||||
}
|
||||
if node.IsGw && node.IngressDNS == "" {
|
||||
node.IngressDNS = "1.1.1.1"
|
||||
}
|
||||
err = logic.UpsertNode(&node)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
proLogic "github.com/gravitl/netmaker/pro/logic"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
controller "github.com/gravitl/netmaker/controllers"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
)
|
||||
|
||||
// RelayHandlers - handle Pro Relays
|
||||
func RelayHandlers(r *mux.Router) {
|
||||
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/createrelay", logic.SecurityCheck(true, http.HandlerFunc(createRelay))).Methods(http.MethodPost)
|
||||
r.HandleFunc("/api/nodes/{network}/{nodeid}/deleterelay", logic.SecurityCheck(true, http.HandlerFunc(deleteRelay))).Methods(http.MethodDelete)
|
||||
r.HandleFunc("/api/v1/host/{hostid}/failoverme", controller.Authorize(true, false, "host", http.HandlerFunc(failOverME))).Methods(http.MethodPost)
|
||||
}
|
||||
|
||||
// @Summary Create a relay
|
||||
// @Router /api/nodes/{network}/{nodeid}/createrelay [post]
|
||||
// @Tags PRO
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param network path string true "Network ID"
|
||||
// @Param nodeid path string true "Node ID"
|
||||
// @Param body body models.RelayRequest true "Relay request parameters"
|
||||
// @Success 200 {object} models.ApiNode
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func createRelay(w http.ResponseWriter, r *http.Request) {
|
||||
var relayRequest models.RelayRequest
|
||||
var params = mux.Vars(r)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
err := json.NewDecoder(r.Body).Decode(&relayRequest)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
relayRequest.NetID = params["network"]
|
||||
relayRequest.NodeID = params["nodeid"]
|
||||
_, relayNode, err := proLogic.CreateRelay(relayRequest)
|
||||
if err != nil {
|
||||
logger.Log(
|
||||
0,
|
||||
r.Header.Get("user"),
|
||||
fmt.Sprintf(
|
||||
"failed to create relay on node [%s] on network [%s]: %v",
|
||||
relayRequest.NodeID,
|
||||
relayRequest.NetID,
|
||||
err,
|
||||
),
|
||||
)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
}
|
||||
for _, relayedNodeID := range relayNode.RelayedNodes {
|
||||
relayedNode, err := logic.GetNodeByID(relayedNodeID)
|
||||
if err == nil {
|
||||
if relayedNode.FailedOverBy != uuid.Nil {
|
||||
go logic.ResetFailedOverPeer(&relayedNode)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
go mq.PublishPeerUpdate(false)
|
||||
logger.Log(
|
||||
1,
|
||||
r.Header.Get("user"),
|
||||
"created relay on node",
|
||||
relayRequest.NodeID,
|
||||
"on network",
|
||||
relayRequest.NetID,
|
||||
)
|
||||
apiNode := relayNode.ConvertToAPINode()
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(apiNode)
|
||||
}
|
||||
|
||||
// @Summary Remove a relay
|
||||
// @Router /api/nodes/{network}/{nodeid}/deleterelay [delete]
|
||||
// @Tags PRO
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param network path string true "Network ID"
|
||||
// @Param nodeid path string true "Node ID"
|
||||
// @Success 200 {object} models.ApiNode
|
||||
// @Failure 400 {object} models.ErrorResponse
|
||||
// @Failure 500 {object} models.ErrorResponse
|
||||
func deleteRelay(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
var params = mux.Vars(r)
|
||||
nodeid := params["nodeid"]
|
||||
netid := params["network"]
|
||||
updateNodes, node, err := proLogic.DeleteRelay(netid, nodeid)
|
||||
if err != nil {
|
||||
logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
logger.Log(1, r.Header.Get("user"), "deleted relay server", nodeid, "on network", netid)
|
||||
go func() {
|
||||
for _, relayedNode := range updateNodes {
|
||||
err = mq.NodeUpdate(&relayedNode)
|
||||
if err != nil {
|
||||
logger.Log(
|
||||
1,
|
||||
"relayed node update ",
|
||||
relayedNode.ID.String(),
|
||||
"on network",
|
||||
relayedNode.Network,
|
||||
": ",
|
||||
err.Error(),
|
||||
)
|
||||
|
||||
}
|
||||
h, err := logic.GetHost(relayedNode.HostID.String())
|
||||
if err == nil {
|
||||
if h.OS == models.OS_Types.IoT {
|
||||
nodes, err := logic.GetAllNodes()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
node.IsRelay = true // for iot update to recognise that it has to delete relay peer
|
||||
if err = mq.PublishSingleHostPeerUpdate(h, nodes, &node, nil, false, nil); err != nil {
|
||||
logger.Log(1, "failed to publish peer update to host", h.ID.String(), ": ", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mq.PublishPeerUpdate(false)
|
||||
}()
|
||||
logger.Log(
|
||||
1,
|
||||
r.Header.Get("user"),
|
||||
"deleted relay on node",
|
||||
node.ID.String(),
|
||||
"on network",
|
||||
node.Network,
|
||||
)
|
||||
apiNode := node.ConvertToAPINode()
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(apiNode)
|
||||
}
|
|
@ -29,7 +29,6 @@ func InitPro() {
|
|||
controller.HttpHandlers = append(
|
||||
controller.HttpHandlers,
|
||||
proControllers.MetricHandlers,
|
||||
proControllers.RelayHandlers,
|
||||
proControllers.UserHandlers,
|
||||
proControllers.FailOverHandlers,
|
||||
proControllers.InetHandlers,
|
||||
|
@ -106,13 +105,6 @@ func InitPro() {
|
|||
logic.GetMetrics = proLogic.GetMetrics
|
||||
logic.UpdateMetrics = proLogic.UpdateMetrics
|
||||
logic.DeleteMetrics = proLogic.DeleteMetrics
|
||||
logic.GetRelays = proLogic.GetRelays
|
||||
logic.GetAllowedIpsForRelayed = proLogic.GetAllowedIpsForRelayed
|
||||
logic.RelayedAllowedIPs = proLogic.RelayedAllowedIPs
|
||||
logic.UpdateRelayed = proLogic.UpdateRelayed
|
||||
logic.SetRelayedNodes = proLogic.SetRelayedNodes
|
||||
logic.RelayUpdates = proLogic.RelayUpdates
|
||||
logic.ValidateRelay = proLogic.ValidateRelay
|
||||
logic.GetTrialEndDate = getTrialEndDate
|
||||
logic.SetDefaultGw = proLogic.SetDefaultGw
|
||||
logic.SetDefaultGwForRelayedUpdate = proLogic.SetDefaultGwForRelayedUpdate
|
||||
|
|
|
@ -1,255 +0,0 @@
|
|||
package logic
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic"
|
||||
"github.com/gravitl/netmaker/logic/acls/nodeacls"
|
||||
"github.com/gravitl/netmaker/models"
|
||||
"github.com/gravitl/netmaker/mq"
|
||||
"github.com/gravitl/netmaker/servercfg"
|
||||
"golang.org/x/exp/slog"
|
||||
)
|
||||
|
||||
// GetRelays - gets all the nodes that are relays
|
||||
func GetRelays() ([]models.Node, error) {
|
||||
nodes, err := logic.GetAllNodes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
relays := make([]models.Node, 0)
|
||||
for _, node := range nodes {
|
||||
if node.IsRelay {
|
||||
relays = append(relays, node)
|
||||
}
|
||||
}
|
||||
return relays, nil
|
||||
}
|
||||
|
||||
// CreateRelay - creates a relay
|
||||
func CreateRelay(relay models.RelayRequest) ([]models.Node, models.Node, error) {
|
||||
var returnnodes []models.Node
|
||||
|
||||
node, err := logic.GetNodeByID(relay.NodeID)
|
||||
if err != nil {
|
||||
return returnnodes, models.Node{}, err
|
||||
}
|
||||
host, err := logic.GetHost(node.HostID.String())
|
||||
if err != nil {
|
||||
return returnnodes, models.Node{}, err
|
||||
}
|
||||
if host.OS != "linux" {
|
||||
return returnnodes, models.Node{}, fmt.Errorf("only linux machines can be relay nodes")
|
||||
}
|
||||
err = ValidateRelay(relay, false)
|
||||
if err != nil {
|
||||
return returnnodes, models.Node{}, err
|
||||
}
|
||||
node.IsRelay = true
|
||||
node.RelayedNodes = relay.RelayedNodes
|
||||
node.SetLastModified()
|
||||
err = logic.UpsertNode(&node)
|
||||
if err != nil {
|
||||
return returnnodes, node, err
|
||||
}
|
||||
returnnodes = SetRelayedNodes(true, relay.NodeID, relay.RelayedNodes)
|
||||
return returnnodes, node, nil
|
||||
}
|
||||
|
||||
// SetRelayedNodes- sets and saves node as relayed
|
||||
func SetRelayedNodes(setRelayed bool, relay string, relayed []string) []models.Node {
|
||||
var returnnodes []models.Node
|
||||
for _, id := range relayed {
|
||||
node, err := logic.GetNodeByID(id)
|
||||
if err != nil {
|
||||
logger.Log(0, "setRelayedNodes.GetNodebyID", err.Error())
|
||||
continue
|
||||
}
|
||||
node.IsRelayed = setRelayed
|
||||
if setRelayed {
|
||||
node.RelayedBy = relay
|
||||
} else {
|
||||
node.RelayedBy = ""
|
||||
}
|
||||
node.SetLastModified()
|
||||
if err := logic.UpsertNode(&node); err != nil {
|
||||
logger.Log(0, "setRelayedNodes.Insert", err.Error())
|
||||
continue
|
||||
}
|
||||
returnnodes = append(returnnodes, node)
|
||||
}
|
||||
return returnnodes
|
||||
}
|
||||
|
||||
// func GetRelayedNodes(relayNode *models.Node) (models.Node, error) {
|
||||
// var returnnodes []models.Node
|
||||
// networkNodes, err := GetNetworkNodes(relayNode.Network)
|
||||
// if err != nil {
|
||||
// return returnnodes, err
|
||||
// }
|
||||
// for _, node := range networkNodes {
|
||||
// for _, addr := range relayNode.RelayAddrs {
|
||||
// if addr == node.Address.IP.String() || addr == node.Address6.IP.String() {
|
||||
// returnnodes = append(returnnodes, node)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return returnnodes, nil
|
||||
// }
|
||||
|
||||
// ValidateRelay - checks if relay is valid
|
||||
func ValidateRelay(relay models.RelayRequest, update bool) error {
|
||||
var err error
|
||||
|
||||
node, err := logic.GetNodeByID(relay.NodeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !update && node.IsRelay {
|
||||
return errors.New("node is already acting as a relay")
|
||||
}
|
||||
for _, relayedNodeID := range relay.RelayedNodes {
|
||||
relayedNode, err := logic.GetNodeByID(relayedNodeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if relayedNode.IsIngressGateway {
|
||||
return errors.New("cannot relay an ingress gateway (" + relayedNodeID + ")")
|
||||
}
|
||||
if relayedNode.IsInternetGateway {
|
||||
return errors.New("cannot relay an internet gateway (" + relayedNodeID + ")")
|
||||
}
|
||||
if relayedNode.InternetGwID != "" && relayedNode.InternetGwID != relay.NodeID {
|
||||
return errors.New("cannot relay an internet client (" + relayedNodeID + ")")
|
||||
}
|
||||
if relayedNode.IsFailOver {
|
||||
return errors.New("cannot relay a failOver (" + relayedNodeID + ")")
|
||||
}
|
||||
if relayedNode.FailedOverBy != uuid.Nil {
|
||||
ResetFailedOverPeer(&relayedNode)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateRelayNodes - updates relay nodes
|
||||
func updateRelayNodes(relay string, oldNodes []string, newNodes []string) []models.Node {
|
||||
_ = SetRelayedNodes(false, relay, oldNodes)
|
||||
return SetRelayedNodes(true, relay, newNodes)
|
||||
}
|
||||
|
||||
func RelayUpdates(currentNode, newNode *models.Node) bool {
|
||||
relayUpdates := false
|
||||
if servercfg.IsPro && newNode.IsRelay {
|
||||
if len(newNode.RelayedNodes) != len(currentNode.RelayedNodes) {
|
||||
relayUpdates = true
|
||||
} else {
|
||||
for i, node := range newNode.RelayedNodes {
|
||||
if node != currentNode.RelayedNodes[i] {
|
||||
relayUpdates = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return relayUpdates
|
||||
}
|
||||
|
||||
// UpdateRelayed - updates a relay's relayed nodes, and sends updates to the relayed nodes over MQ
|
||||
func UpdateRelayed(currentNode, newNode *models.Node) {
|
||||
updatenodes := updateRelayNodes(currentNode.ID.String(), currentNode.RelayedNodes, newNode.RelayedNodes)
|
||||
if len(updatenodes) > 0 {
|
||||
for _, relayedNode := range updatenodes {
|
||||
node := relayedNode
|
||||
ResetFailedOverPeer(&node)
|
||||
go func() {
|
||||
if err := mq.NodeUpdate(&node); err != nil {
|
||||
slog.Error("error publishing node update to node", "node", node.ID, "error", err)
|
||||
}
|
||||
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteRelay - deletes a relay
|
||||
func DeleteRelay(network, nodeid string) ([]models.Node, models.Node, error) {
|
||||
var returnnodes []models.Node
|
||||
node, err := logic.GetNodeByID(nodeid)
|
||||
if err != nil {
|
||||
return returnnodes, models.Node{}, err
|
||||
}
|
||||
returnnodes = SetRelayedNodes(false, nodeid, node.RelayedNodes)
|
||||
node.IsRelay = false
|
||||
node.RelayedNodes = []string{}
|
||||
node.SetLastModified()
|
||||
if err = logic.UpsertNode(&node); err != nil {
|
||||
return returnnodes, models.Node{}, err
|
||||
}
|
||||
return returnnodes, node, nil
|
||||
}
|
||||
|
||||
func RelayedAllowedIPs(peer, node *models.Node) []net.IPNet {
|
||||
var allowedIPs = []net.IPNet{}
|
||||
for _, relayedNodeID := range peer.RelayedNodes {
|
||||
if node.ID.String() == relayedNodeID {
|
||||
continue
|
||||
}
|
||||
relayedNode, err := logic.GetNodeByID(relayedNodeID)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
allowed := getRelayedAddresses(relayedNodeID)
|
||||
if relayedNode.IsEgressGateway {
|
||||
allowed = append(allowed, logic.GetEgressIPs(&relayedNode)...)
|
||||
}
|
||||
allowedIPs = append(allowedIPs, allowed...)
|
||||
}
|
||||
return allowedIPs
|
||||
}
|
||||
|
||||
// GetAllowedIpsForRelayed - returns the peerConfig for a node relayed by relay
|
||||
func GetAllowedIpsForRelayed(relayed, relay *models.Node) (allowedIPs []net.IPNet) {
|
||||
if relayed.RelayedBy != relay.ID.String() {
|
||||
logger.Log(0, "RelayedByRelay called with invalid parameters")
|
||||
return
|
||||
}
|
||||
if relay.InternetGwID != "" {
|
||||
return GetAllowedIpForInetNodeClient(relayed, relay)
|
||||
}
|
||||
peers, err := logic.GetNetworkNodes(relay.Network)
|
||||
if err != nil {
|
||||
logger.Log(0, "error getting network clients", err.Error())
|
||||
return
|
||||
}
|
||||
for _, peer := range peers {
|
||||
if peer.ID == relayed.ID || peer.ID == relay.ID {
|
||||
continue
|
||||
}
|
||||
if nodeacls.AreNodesAllowed(nodeacls.NetworkID(relayed.Network), nodeacls.NodeID(relayed.ID.String()), nodeacls.NodeID(peer.ID.String())) {
|
||||
allowedIPs = append(allowedIPs, logic.GetAllowedIPs(relayed, &peer, nil)...)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getRelayedAddresses(id string) []net.IPNet {
|
||||
addrs := []net.IPNet{}
|
||||
node, err := logic.GetNodeByID(id)
|
||||
if err != nil {
|
||||
logger.Log(0, "getRelayedAddresses: "+err.Error())
|
||||
return addrs
|
||||
}
|
||||
if node.Address.IP != nil {
|
||||
node.Address.Mask = net.CIDRMask(32, 32)
|
||||
addrs = append(addrs, node.Address)
|
||||
}
|
||||
if node.Address6.IP != nil {
|
||||
node.Address6.Mask = net.CIDRMask(128, 128)
|
||||
addrs = append(addrs, node.Address6)
|
||||
}
|
||||
return addrs
|
||||
}
|
Loading…
Add table
Reference in a new issue