setup user access middlerware controller

This commit is contained in:
abhishek9686 2024-06-11 07:32:10 +05:30
commit 6eaedc5fb0
27 changed files with 249 additions and 85 deletions

View file

@ -6,7 +6,7 @@ COPY . .
RUN GOOS=linux CGO_ENABLED=1 go build -ldflags="-s -w " -tags ${tags} .
# RUN go build -tags=ee . -o netmaker main.go
FROM alpine:3.19.1
FROM alpine:3.20.0
# add a c lib
# set the working directory

View file

@ -1,5 +1,5 @@
#first stage - builder
FROM alpine:3.19.1
FROM alpine:3.20.0
ARG version
WORKDIR /app
COPY ./netmaker /root/netmaker

View file

@ -18,6 +18,7 @@ var (
name string
listenPort int
mtu int
isStaticPort bool
isStatic bool
isDefault bool
keepAlive int
@ -45,6 +46,7 @@ var hostUpdateCmd = &cobra.Command{
apiHost.Name = name
apiHost.ListenPort = listenPort
apiHost.MTU = mtu
apiHost.IsStaticPort = isStaticPort
apiHost.IsStatic = isStatic
apiHost.IsDefault = isDefault
apiHost.PersistentKeepalive = keepAlive
@ -61,7 +63,8 @@ func init() {
hostUpdateCmd.Flags().IntVar(&listenPort, "listen_port", 0, "Listen port of the host")
hostUpdateCmd.Flags().IntVar(&mtu, "mtu", 0, "Host MTU size")
hostUpdateCmd.Flags().IntVar(&keepAlive, "keep_alive", 0, "Interval (seconds) in which packets are sent to keep connections open with peers")
hostUpdateCmd.Flags().BoolVar(&isStatic, "static", false, "Make Host Static ?")
hostUpdateCmd.Flags().BoolVar(&isStaticPort, "static_port", false, "Make Host Static Port?")
hostUpdateCmd.Flags().BoolVar(&isStatic, "static_endpoint", false, "Make Host Static Endpoint?")
hostUpdateCmd.Flags().BoolVar(&isDefault, "default", false, "Make Host Default ?")
rootCmd.AddCommand(hostUpdateCmd)
}

View file

@ -17,7 +17,9 @@ import (
)
// HttpMiddlewares - middleware functions for REST interactions
var HttpMiddlewares []mux.MiddlewareFunc
var HttpMiddlewares = []mux.MiddlewareFunc{
userMiddleWare,
}
// HttpHandlers - handler functions for REST interactions
var HttpHandlers = []interface{}{

View file

@ -304,17 +304,17 @@ func deleteHost(w http.ResponseWriter, r *http.Request) {
slog.Error("failed to remove host credentials from EMQX", "id", currHost.ID, "error", err)
}
}
if err = logic.RemoveHost(currHost, forceDelete); err != nil {
logger.Log(0, r.Header.Get("user"), "failed to delete a host:", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
if err = mq.HostUpdate(&models.HostUpdate{
Action: models.DeleteHost,
Host: *currHost,
}); err != nil {
logger.Log(0, r.Header.Get("user"), "failed to send delete host update: ", currHost.ID.String(), err.Error())
}
if err = logic.RemoveHost(currHost, forceDelete); err != nil {
logger.Log(0, r.Header.Get("user"), "failed to delete a host:", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
apiHostData := currHost.ConvertNMHostToAPI()
logger.Log(2, r.Header.Get("user"), "removed host", currHost.Name)

63
controllers/middleware.go Normal file
View file

@ -0,0 +1,63 @@
package controller
import (
"net/http"
"strings"
"github.com/gorilla/mux"
"github.com/gravitl/netmaker/models"
)
func userMiddleWare(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var params = mux.Vars(r)
r.Header.Set("NET_ID", params["network"])
if strings.Contains(r.URL.Path, "host") || strings.Contains(r.URL.Path, "node") {
r.Header.Set("TARGET_RSRC", models.HostRsrc.String())
r.Header.Set("RSRC_TYPE", models.HostRsrc.String())
}
if strings.Contains(r.URL.Path, "dns") {
r.Header.Set("RSRC_TYPE", models.DnsRsrc.String())
r.Header.Set("TARGET_RSRC", models.DnsRsrc.String())
}
if strings.Contains(r.URL.Path, "users") {
r.Header.Set("RSRC_TYPE", models.UserRsrc.String())
r.Header.Set("TARGET_RSRC", models.UserRsrc.String())
}
if strings.Contains(r.URL.Path, "ingress") {
r.Header.Set("TARGET_RSRC", models.RemoteAccessGwRsrc.String())
}
if strings.Contains(r.URL.Path, "gateway") {
r.Header.Set("TARGET_RSRC", models.EgressGwRsrc.String())
}
if strings.Contains(r.URL.Path, "networks") {
r.Header.Set("TARGET_RSRC", models.NetworkRsrc.String())
r.Header.Set("RSRC_TYPE", models.NetworkRsrc.String())
}
if strings.Contains(r.URL.Path, "extclients") {
r.Header.Set("TARGET_RSRC", models.ExtClientsRsrc.String())
r.Header.Set("RSRC_TYPE", models.ExtClientsRsrc.String())
}
if nodeID, ok := params["nodeid"]; ok {
r.Header.Set("TARGET_RSRC_ID", nodeID)
}
if hostID, ok := params["hostid"]; ok {
r.Header.Set("TARGET_RSRC_ID", hostID)
}
if clientID, ok := params["clientid"]; ok {
r.Header.Set("TARGET_RSRC_ID", clientID)
}
if netID, ok := params["networkname"]; ok {
r.Header.Set("TARGET_RSRC_ID", netID)
}
if userID, ok := params["username"]; ok {
r.Header.Set("TARGET_RSRC_ID", userID)
}
if r.Header.Get("TARGET_RSRC_ID") == "" {
r.Header.Set("IS_GLOBAL_ACCESS", "yes")
}
// pro
handler.ServeHTTP(w, r)
})
}

View file

@ -150,6 +150,7 @@ func convertLegacyHostNode(legacy models.LegacyNode) (models.Host, models.Node)
host.EndpointIP = net.ParseIP(legacy.Endpoint)
host.IsDocker = models.ParseBool(legacy.IsDocker)
host.IsK8S = models.ParseBool(legacy.IsK8S)
host.IsStaticPort = models.ParseBool(legacy.IsStatic)
host.IsStatic = models.ParseBool(legacy.IsStatic)
host.PersistentKeepalive = time.Duration(legacy.PersistentKeepalive) * time.Second
if host.PersistentKeepalive == 0 {

2
go.mod
View file

@ -57,7 +57,7 @@ require (
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/go-version v1.7.0
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect

4
go.sum
View file

@ -41,8 +41,8 @@ github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/guumaster/tablewriter v0.0.10 h1:A0HD94yMdt4usgxBjoEceNeE0XMJ027euoHAzsPqBQs=
github.com/guumaster/tablewriter v0.0.10/go.mod h1:p4FRFhyfo0UD9ZLmMRbbJooTUsxo6b80qZTERVDWrH8=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=

View file

@ -23,6 +23,8 @@ spec:
volumeMounts:
- mountPath: /etc/netclient
name: etc-netclient
- mountPath: /var/log
name: log-netclient
securityContext:
privileged: true
volumes:
@ -32,3 +34,6 @@ spec:
path: /etc/netclient
type: DirectoryOrCreate
name: etc-netclient
- emptyDir:
medium: Memory
name: log-netclient

View file

@ -35,6 +35,8 @@ spec:
volumeMounts:
- mountPath: /etc/netclient
name: etc-netclient
- mountPath: /var/log
name: log-netclient
securityContext:
privileged: true
volumes:
@ -42,3 +44,6 @@ spec:
path: /etc/netclient
type: DirectoryOrCreate
name: etc-netclient
- emptyDir:
medium: Memory
name: log-netclient

View file

@ -376,7 +376,7 @@ func ToggleExtClientConnectivity(client *models.ExtClient, enable bool) (models.
return newClient, nil
}
func getExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, []models.EgressNetworkRoutes, error) {
func GetExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandAddr, []models.EgressNetworkRoutes, error) {
var peers []wgtypes.PeerConfig
var idsAndAddr []models.IDandAddr
var egressRoutes []models.EgressNetworkRoutes
@ -431,7 +431,7 @@ func getExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandA
allowedips = append(allowedips, *cidr)
}
}
egressRoutes = append(egressRoutes, getExtPeerEgressRoute(extPeer)...)
egressRoutes = append(egressRoutes, getExtPeerEgressRoute(*node, extPeer)...)
primaryAddr := extPeer.Address
if primaryAddr == "" {
primaryAddr = extPeer.Address6
@ -453,23 +453,18 @@ func getExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandA
}
func getExtPeerEgressRoute(extPeer models.ExtClient) (egressRoutes []models.EgressNetworkRoutes) {
if extPeer.Address != "" {
egressRoutes = append(egressRoutes, models.EgressNetworkRoutes{
NodeAddr: extPeer.AddressIPNet4(),
EgressRanges: extPeer.ExtraAllowedIPs,
})
}
if extPeer.Address6 != "" {
egressRoutes = append(egressRoutes, models.EgressNetworkRoutes{
NodeAddr: extPeer.AddressIPNet6(),
EgressRanges: extPeer.ExtraAllowedIPs,
})
}
func getExtPeerEgressRoute(node models.Node, extPeer models.ExtClient) (egressRoutes []models.EgressNetworkRoutes) {
egressRoutes = append(egressRoutes, models.EgressNetworkRoutes{
EgressGwAddr: extPeer.AddressIPNet4(),
EgressGwAddr6: extPeer.AddressIPNet6(),
NodeAddr: node.Address,
NodeAddr6: node.Address6,
EgressRanges: extPeer.ExtraAllowedIPs,
})
return
}
func getExtpeersExtraRoutes(network string) (egressRoutes []models.EgressNetworkRoutes) {
func getExtpeersExtraRoutes(node models.Node, network string) (egressRoutes []models.EgressNetworkRoutes) {
extPeers, err := GetNetworkExtClients(network)
if err != nil {
return
@ -478,7 +473,7 @@ func getExtpeersExtraRoutes(network string) (egressRoutes []models.EgressNetwork
if len(extPeer.ExtraAllowedIPs) == 0 {
continue
}
egressRoutes = append(egressRoutes, getExtPeerEgressRoute(extPeer)...)
egressRoutes = append(egressRoutes, getExtPeerEgressRoute(node, extPeer)...)
}
return
}

View file

@ -170,6 +170,7 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq
}
}
node.SetLastModified()
node.Metadata = ingress.Metadata
if node.Metadata == "" {
node.Metadata = "This host can be used for remote access"
}

View file

@ -266,6 +266,7 @@ func UpdateHostFromClient(newHost, currHost *models.Host) (sendPeerUpdate bool)
currHost.Debug = newHost.Debug
currHost.Verbosity = newHost.Verbosity
currHost.Version = newHost.Version
currHost.IsStaticPort = newHost.IsStaticPort
currHost.IsStatic = newHost.IsStatic
currHost.MTU = newHost.MTU
currHost.Name = newHost.Name
@ -396,20 +397,13 @@ func DissasociateNodeFromHost(n *models.Node, h *models.Host) error {
if len(h.Nodes) == 0 {
return fmt.Errorf("no nodes present in given host")
}
index := -1
nList := []string{}
for i := range h.Nodes {
if h.Nodes[i] == n.ID.String() {
index = i
break
if h.Nodes[i] != n.ID.String() {
nList = append(nList, h.Nodes[i])
}
}
if index < 0 {
if len(h.Nodes) == 0 {
return fmt.Errorf("node %s, not found in host, %s", n.ID.String(), h.ID.String())
}
} else {
h.Nodes = RemoveStringSlice(h.Nodes, index)
}
h.Nodes = nList
go func() {
if servercfg.IsPro {
if clients, err := GetNetworkExtClients(n.Network); err != nil {
@ -434,7 +428,7 @@ func DisassociateAllNodesFromHost(hostID string) error {
for _, nodeID := range host.Nodes {
node, err := GetNodeByID(nodeID)
if err != nil {
logger.Log(0, "failed to get host node", err.Error())
logger.Log(0, "failed to get host node, node id:", nodeID, err.Error())
continue
}
if err := DeleteNode(&node, true); err != nil {

View file

@ -181,7 +181,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
})
}
if peer.IsIngressGateway {
hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(peer.Network)...)
hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(node, peer.Network)...)
}
_, isFailOverPeer := node.FailOverPeers[peer.ID.String()]
if servercfg.IsPro {
@ -249,9 +249,10 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, peerConfig)
peerIndexMap[peerHost.PublicKey.String()] = len(hostPeerUpdate.Peers) - 1
hostPeerUpdate.HostNetworkInfo[peerHost.PublicKey.String()] = models.HostNetworkInfo{
Interfaces: peerHost.Interfaces,
ListenPort: peerHost.ListenPort,
IsStatic: peerHost.IsStatic,
Interfaces: peerHost.Interfaces,
ListenPort: peerHost.ListenPort,
IsStaticPort: peerHost.IsStaticPort,
IsStatic: peerHost.IsStatic,
}
nodePeer = peerConfig
} else {
@ -260,9 +261,10 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].AllowedIPs = peerAllowedIPs
hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]].Remove = false
hostPeerUpdate.HostNetworkInfo[peerHost.PublicKey.String()] = models.HostNetworkInfo{
Interfaces: peerHost.Interfaces,
ListenPort: peerHost.ListenPort,
IsStatic: peerHost.IsStatic,
Interfaces: peerHost.Interfaces,
ListenPort: peerHost.ListenPort,
IsStaticPort: peerHost.IsStaticPort,
IsStatic: peerHost.IsStatic,
}
nodePeer = hostPeerUpdate.Peers[peerIndexMap[peerHost.PublicKey.String()]]
}
@ -283,7 +285,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
var extPeerIDAndAddrs []models.IDandAddr
var egressRoutes []models.EgressNetworkRoutes
if node.IsIngressGateway {
extPeers, extPeerIDAndAddrs, egressRoutes, err = getExtPeers(&node, &node)
extPeers, extPeerIDAndAddrs, egressRoutes, err = GetExtPeers(&node, &node)
if err == nil {
hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, egressRoutes...)
hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
@ -415,7 +417,7 @@ func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet
// handle ingress gateway peers
if peer.IsIngressGateway {
extPeers, _, _, err := getExtPeers(peer, node)
extPeers, _, _, err := GetExtPeers(peer, node)
if err != nil {
logger.Log(2, "could not retrieve ext peers for ", peer.ID.String(), err.Error())
}

View file

@ -15,6 +15,7 @@ type ApiHost struct {
Name string `json:"name"`
OS string `json:"os"`
Debug bool `json:"debug"`
IsStaticPort bool `json:"isstaticport"`
IsStatic bool `json:"isstatic"`
ListenPort int `json:"listenport"`
WgPublicListenPort int `json:"wg_public_listen_port" yaml:"wg_public_listen_port"`
@ -61,6 +62,7 @@ func (h *Host) ConvertNMHostToAPI() *ApiHost {
}
}
a.DefaultInterface = h.DefaultInterface
a.IsStaticPort = h.IsStaticPort
a.IsStatic = h.IsStatic
a.ListenPort = h.ListenPort
a.MTU = h.MTU
@ -104,6 +106,7 @@ func (a *ApiHost) ConvertAPIHostToNMHost(currentHost *Host) *Host {
h.DefaultInterface = currentHost.DefaultInterface
h.IsDocker = currentHost.IsDocker
h.IsK8S = currentHost.IsK8S
h.IsStaticPort = a.IsStaticPort
h.IsStatic = a.IsStatic
h.ListenPort = a.ListenPort
h.MTU = a.MTU

View file

@ -66,7 +66,8 @@ type Host struct {
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"`
IsStaticPort bool `json:"isstaticport" yaml:"isstaticport"`
IsStatic bool `json:"isstatic" yaml:"isstatic"`
IsDefault bool `json:"isdefault" yaml:"isdefault"`
NatType string `json:"nat_type,omitempty" yaml:"nat_type,omitempty"`
TurnEndpoint *netip.AddrPort `json:"turn_endpoint,omitempty" yaml:"turn_endpoint,omitempty"`

View file

@ -42,9 +42,10 @@ type HostInfoMap map[string]HostNetworkInfo
// HostNetworkInfo - holds info related to host networking (used for client side peer calculations)
type HostNetworkInfo struct {
Interfaces []Iface `json:"interfaces" yaml:"interfaces"`
ListenPort int `json:"listen_port" yaml:"listen_port"`
IsStatic bool `json:"is_static"`
Interfaces []Iface `json:"interfaces" yaml:"interfaces"`
ListenPort int `json:"listen_port" yaml:"listen_port"`
IsStaticPort bool `json:"is_static_port"`
IsStatic bool `json:"is_static"`
}
// PeerMap - peer map for ids and addresses in metrics

View file

@ -42,6 +42,7 @@ type UserRemoteGws struct {
GwListenPort int `json:"gw_listen_port"`
Metadata string `json:"metadata"`
AllowedEndpoints []string `json:"allowed_endpoints"`
NetworkAddresses []string `json:"network_addresses"`
}
// UserRemoteGwsReq - struct to hold user remote acccess gws req
@ -164,6 +165,7 @@ type HostRelayRequest struct {
type IngressRequest struct {
ExtclientDNS string `json:"extclientdns"`
IsInternetGateway bool `json:"is_internet_gw"`
Metadata string `json:"metadata"`
}
// InetNodeReq - exit node request struct

View file

@ -12,27 +12,37 @@ type RsrcID string
type UserRole string
type UserGroupID string
func (r RsrcType) String() string {
return string(r)
}
const (
HostRsrc RsrcType = "hosts"
RelayRsrc RsrcType = "relays"
RemoteAccessGwRsrc RsrcType = "remote_access_gw"
ExtClientsRsrc RsrcType = "extclients"
InetGwRsrc RsrcType = "inet_gw"
EgressGwRsrc RsrcType = "egress"
NetworkRsrc RsrcType = "networks"
EnrollmentKeysRsrc RsrcType = "enrollment_key"
UserRsrc RsrcType = "users"
AclRsrc RsrcType = "acl"
DnsRsrc RsrcType = "dns"
FailOverRsrc RsrcType = "fail_over"
)
const (
AllHostRsrcID RsrcID = "all_host"
AllRelayRsrcID RsrcID = "all_relay"
AllRemoteAccessGwRsrcID RsrcID = "all_remote_access_gw"
AllExtClientsRsrc RsrcID = "all_extclients"
AllInetGwRsrcID RsrcID = "all_inet_gw"
AllEgressGwRsrcID RsrcID = "all_egress"
AllNetworkRsrcID RsrcID = "all_network"
AllEnrollmentKeysRsrcID RsrcID = "all_enrollment_key"
AllUserRsrcID RsrcID = "all_user"
AllDnsRsrcID RsrcID = "all_dns"
AllFailOverRsrc RsrcID = "all_fail_over"
)
// Pre-Defined User Roles

View file

@ -201,20 +201,7 @@ func signalPeer(signal models.Signal) {
slog.Error("failed to signal, peer host not found", "error", err)
return
}
peerNode, err := logic.GetNodeByID(signal.ToNodeID)
if err != nil {
slog.Error("failed to signal, node not found", "error", err)
return
}
node, err := logic.GetNodeByID(signal.FromNodeID)
if err != nil {
slog.Error("failed to signal, peer node not found", "error", err)
return
}
if peerNode.IsIngressGateway || node.IsIngressGateway || peerNode.IsInternetGateway || node.IsInternetGateway {
signal.Action = ""
return
}
err = HostUpdate(&models.HostUpdate{
Action: models.SignalHost,
Host: *peerHost,

View file

@ -6,6 +6,7 @@ import (
"net/http"
"github.com/gravitl/netmaker/auth"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/logic/pro/netcache"
@ -58,10 +59,20 @@ func HandleHeadlessSSOCallback(w http.ResponseWriter, r *http.Request) {
}
user, err := logic.GetUser(userClaims.getUserName())
if err != nil {
response := returnErrTemplate("", "user not found", state, reqKeyIf)
w.WriteHeader(http.StatusForbidden)
w.Write(response)
return
if database.IsEmptyRecord(err) { // user must not exist, so try to make one
err = logic.InsertPendingUser(&models.User{
UserName: userClaims.getUserName(),
})
if err != nil {
handleSomethingWentWrong(w)
return
}
handleFirstTimeOauthUserSignUp(w)
return
} else {
handleSomethingWentWrong(w)
return
}
}
newPass, fetchErr := auth.FetchPassValue("")
if fetchErr != nil {

View file

@ -159,12 +159,24 @@ func failOverME(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("peer not found"), "badrequest"))
return
}
if node.IsRelayed || node.IsFailOver {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node is relayed or acting as failover"), "badrequest"))
if node.IsFailOver {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node is acting as failover"), "badrequest"))
return
}
if peerNode.IsRelayed || peerNode.IsFailOver {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("peer node is relayed or acting as failover"), "badrequest"))
if node.IsRelayed && node.RelayedBy == peerNode.ID.String() {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node is relayed by peer node"), "badrequest"))
return
}
if node.IsRelay && peerNode.RelayedBy == node.ID.String() {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node acting as relay for the peer node"), "badrequest"))
return
}
if node.IsInternetGateway && peerNode.InternetGwID == node.ID.String() {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node acting as internet gw for the peer node"), "badrequest"))
return
}
if node.InternetGwID != "" && node.InternetGwID == peerNode.ID.String() {
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("node using a internet gw by the peer node"), "badrequest"))
return
}

View file

@ -214,6 +214,10 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
if err != nil {
continue
}
network, err := logic.GetNetwork(node.Network)
if err != nil {
slog.Error("failed to get node network", "error", err)
}
if _, ok := user.RemoteGwIDs[node.ID.String()]; (!user.IsAdmin && !user.IsSuperAdmin) && ok {
gws := userGws[node.Network]
@ -229,6 +233,7 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
GwListenPort: logic.GetPeerListenPort(host),
Metadata: node.Metadata,
AllowedEndpoints: getAllowedRagEndpoints(&node, host),
NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
})
userGws[node.Network] = gws
delete(user.RemoteGwIDs, node.ID.String())
@ -246,6 +251,7 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
GwListenPort: logic.GetPeerListenPort(host),
Metadata: node.Metadata,
AllowedEndpoints: getAllowedRagEndpoints(&node, host),
NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
})
userGws[node.Network] = gws
processedAdminNodeIds[node.ID.String()] = struct{}{}
@ -270,6 +276,10 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
if err != nil {
continue
}
network, err := logic.GetNetwork(node.Network)
if err != nil {
slog.Error("failed to get node network", "error", err)
}
gws := userGws[node.Network]
gws = append(gws, models.UserRemoteGws{
@ -281,6 +291,7 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
GwListenPort: logic.GetPeerListenPort(host),
Metadata: node.Metadata,
AllowedEndpoints: getAllowedRagEndpoints(&node, host),
NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
})
userGws[node.Network] = gws
}
@ -299,6 +310,10 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
slog.Error("failed to fetch host", "error", err)
continue
}
network, err := logic.GetNetwork(node.Network)
if err != nil {
slog.Error("failed to get node network", "error", err)
}
gws := userGws[node.Network]
gws = append(gws, models.UserRemoteGws{
@ -310,6 +325,7 @@ func getUserRemoteAccessGws(w http.ResponseWriter, r *http.Request) {
GwListenPort: logic.GetPeerListenPort(host),
Metadata: node.Metadata,
AllowedEndpoints: getAllowedRagEndpoints(&node, host),
NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
})
userGws[node.Network] = gws
}

View file

@ -5,15 +5,14 @@ import (
"net"
"github.com/google/uuid"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
"golang.org/x/exp/slog"
)
func SetFailOverCtx(failOverNode, victimNode, peerNode models.Node) error {
if victimNode.IsIngressGateway || peerNode.IsIngressGateway || victimNode.IsInternetGateway || peerNode.IsInternetGateway {
return nil
}
if peerNode.FailOverPeers == nil {
peerNode.FailOverPeers = make(map[string]struct{})
}
@ -125,7 +124,38 @@ func GetFailOverPeerIps(peer, node *models.Node) []net.IPNet {
if failOverpeer.IsEgressGateway {
allowedips = append(allowedips, logic.GetEgressIPs(&failOverpeer)...)
}
if failOverpeer.IsRelay {
for _, id := range failOverpeer.RelayedNodes {
rNode, _ := logic.GetNodeByID(id)
if rNode.Address.IP != nil {
allowed := net.IPNet{
IP: rNode.Address.IP,
Mask: net.CIDRMask(32, 32),
}
allowedips = append(allowedips, allowed)
}
if rNode.Address6.IP != nil {
allowed := net.IPNet{
IP: rNode.Address6.IP,
Mask: net.CIDRMask(128, 128),
}
allowedips = append(allowedips, allowed)
}
if rNode.IsEgressGateway {
allowedips = append(allowedips, logic.GetEgressIPs(&rNode)...)
}
}
}
// handle ingress gateway peers
if failOverpeer.IsIngressGateway {
extPeers, _, _, err := logic.GetExtPeers(&failOverpeer, node)
if err != nil {
logger.Log(2, "could not retrieve ext peers for ", peer.ID.String(), err.Error())
}
for _, extPeer := range extPeers {
allowedips = append(allowedips, extPeer.AllowedIPs...)
}
}
}
}
return allowedips
@ -140,10 +170,10 @@ func CreateFailOver(node models.Node) error {
return err
}
if host.OS != models.OS_Types.Linux {
return err
return errors.New("only linux nodes are allowed to be set as failover")
}
if node.IsRelayed {
return err
return errors.New("relayed node cannot be set as failover")
}
node.IsFailOver = true
err = logic.UpsertNode(&node)

View file

@ -5,6 +5,7 @@ import (
"fmt"
"net"
"github.com/google/uuid"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
"golang.org/x/exp/slog"
@ -29,6 +30,7 @@ func ValidateInetGwReq(inetNode models.Node, req models.InetNodeReq, update bool
if inetNode.IsRelayed {
return fmt.Errorf("node %s is being relayed", inetHost.Name)
}
for _, clientNodeID := range req.InetNodeClientIDs {
clientNode, err := logic.GetNodeByID(clientNodeID)
if err != nil {
@ -53,6 +55,9 @@ func ValidateInetGwReq(inetNode models.Node, req models.InetNodeReq, update bool
return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
}
}
if clientNode.FailedOverBy != uuid.Nil {
ResetFailedOverPeer(&clientNode)
}
if clientNode.IsRelayed {
return fmt.Errorf("node %s is being relayed", clientHost.Name)
@ -107,9 +112,13 @@ func UnsetInternetGw(node *models.Node) {
func SetDefaultGwForRelayedUpdate(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
if relay.InternetGwID != "" {
relayedHost, err := logic.GetHost(relayed.HostID.String())
if err != nil {
return peerUpdate
}
peerUpdate.ChangeDefaultGw = true
peerUpdate.DefaultGwIp = relay.Address.IP
if peerUpdate.DefaultGwIp == nil {
if peerUpdate.DefaultGwIp == nil || relayedHost.EndpointIP == nil {
peerUpdate.DefaultGwIp = relay.Address6.IP
}
@ -124,9 +133,14 @@ func SetDefaultGw(node models.Node, peerUpdate models.HostPeerUpdate) models.Hos
if err != nil {
return peerUpdate
}
host, err := logic.GetHost(node.HostID.String())
if err != nil {
return peerUpdate
}
peerUpdate.ChangeDefaultGw = true
peerUpdate.DefaultGwIp = inetNode.Address.IP
if peerUpdate.DefaultGwIp == nil {
if peerUpdate.DefaultGwIp == nil || host.EndpointIP == nil {
peerUpdate.DefaultGwIp = inetNode.Address6.IP
}
}
@ -155,7 +169,6 @@ func GetAllowedIpForInetNodeClient(node, peer *models.Node) []net.IPNet {
if peer.Address.IP != nil {
_, ipnet, _ := net.ParseCIDR(IPv4Network)
allowedips = append(allowedips, *ipnet)
return allowedips
}
if peer.Address6.IP != nil {

View file

@ -5,6 +5,7 @@ import (
"fmt"
"net"
"github.com/google/uuid"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/logic/acls/nodeacls"
@ -122,6 +123,12 @@ func ValidateRelay(relay models.RelayRequest, update bool) error {
if relayedNode.IsInternetGateway {
return errors.New("cannot relay an internet gateway (" + relayedNodeID + ")")
}
if relayedNode.IsFailOver {
return errors.New("cannot relay a failOver (" + relayedNodeID + ")")
}
if relayedNode.FailedOverBy != uuid.Nil {
ResetFailedOverPeer(&relayedNode)
}
}
return err
}