Browse Source

Merge branch 'develop' of https://github.com/gravitl/netmaker into NET-1252

abhishek9686 1 year ago
parent
commit
d526b2a4da

+ 1 - 0
.github/ISSUE_TEMPLATE/bug-report.yml

@@ -31,6 +31,7 @@ body:
       label: Version
       label: Version
       description: What version are you running?
       description: What version are you running?
       options:
       options:
+        - v0.24.2
         - v0.24.1
         - v0.24.1
         - v0.24.0
         - v0.24.0
         - v0.23.0
         - v0.23.0

+ 15 - 0
.github/workflows/sendtokitemaker.yml

@@ -0,0 +1,15 @@
+name: Send to Kitemaker
+
+on:
+    issues:
+        types: opened
+
+
+jobs:
+    send-ticket:
+        uses: gravitl/devops/.github/workflows/makekitemakerticket.yml@master
+        with:
+            title: ${{ github.event.issue.title }}
+            body: ${{ github.event.issue.body }}
+            repo_name: ${{ github.event.repository.name }}
+        secrets: inherit

+ 1 - 1
Dockerfile

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

+ 1 - 1
Dockerfile-quick

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

+ 1 - 1
README.md

@@ -16,7 +16,7 @@
 
 
 <p align="center">
 <p align="center">
   <a href="https://github.com/gravitl/netmaker/releases">
   <a href="https://github.com/gravitl/netmaker/releases">
-    <img src="https://img.shields.io/badge/Version-0.24.1-informational?style=flat-square" />
+    <img src="https://img.shields.io/badge/Version-0.24.2-informational?style=flat-square" />
   </a>
   </a>
   <a href="https://hub.docker.com/r/gravitl/netmaker/tags">
   <a href="https://hub.docker.com/r/gravitl/netmaker/tags">
     <img src="https://img.shields.io/docker/pulls/gravitl/netmaker?label=downloads" />
     <img src="https://img.shields.io/docker/pulls/gravitl/netmaker?label=downloads" />

+ 1 - 1
compose/docker-compose.netclient.yml

@@ -3,7 +3,7 @@ version: "3.4"
 services:
 services:
   netclient:
   netclient:
     container_name: netclient
     container_name: netclient
-    image: 'gravitl/netclient:v0.24.1'
+    image: 'gravitl/netclient:v0.24.2'
     hostname: netmaker-1
     hostname: netmaker-1
     network_mode: host
     network_mode: host
     restart: on-failure
     restart: on-failure

+ 1 - 1
controllers/docs.go

@@ -10,7 +10,7 @@
 //
 //
 //	Schemes: https
 //	Schemes: https
 //	BasePath: /
 //	BasePath: /
-//	Version: 0.24.1
+//	Version: 0.24.2
 //	Host: api.demo.netmaker.io
 //	Host: api.demo.netmaker.io
 //
 //
 //	Consumes:
 //	Consumes:

+ 5 - 5
controllers/hosts.go

@@ -303,17 +303,17 @@ func deleteHost(w http.ResponseWriter, r *http.Request) {
 			slog.Error("failed to remove host credentials from EMQX", "id", currHost.ID, "error", err)
 			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{
 	if err = mq.HostUpdate(&models.HostUpdate{
 		Action: models.DeleteHost,
 		Action: models.DeleteHost,
 		Host:   *currHost,
 		Host:   *currHost,
 	}); err != nil {
 	}); err != nil {
 		logger.Log(0, r.Header.Get("user"), "failed to send delete host update: ", currHost.ID.String(), err.Error())
 		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()
 	apiHostData := currHost.ConvertNMHostToAPI()
 	logger.Log(2, r.Header.Get("user"), "removed host", currHost.Name)
 	logger.Log(2, r.Header.Get("user"), "removed host", currHost.Name)

+ 1 - 1
go.mod

@@ -57,7 +57,7 @@ require (
 	github.com/felixge/httpsnoop v1.0.3 // indirect
 	github.com/felixge/httpsnoop v1.0.3 // indirect
 	github.com/go-playground/locales v0.14.1 // indirect
 	github.com/go-playground/locales v0.14.1 // indirect
 	github.com/go-playground/universal-translator v0.18.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/leodido/go-urn v1.4.0 // indirect
 	github.com/mattn/go-runewidth v0.0.13 // indirect
 	github.com/mattn/go-runewidth v0.0.13 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect

+ 2 - 2
go.sum

@@ -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/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 h1:A0HD94yMdt4usgxBjoEceNeE0XMJ027euoHAzsPqBQs=
 github.com/guumaster/tablewriter v0.0.10/go.mod h1:p4FRFhyfo0UD9ZLmMRbbJooTUsxo6b80qZTERVDWrH8=
 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 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
 github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=

+ 6 - 1
k8s/client/netclient-daemonset.yaml

@@ -16,13 +16,15 @@ spec:
       hostNetwork: true
       hostNetwork: true
       containers:
       containers:
       - name: netclient
       - name: netclient
-        image: gravitl/netclient:v0.24.1
+        image: gravitl/netclient:v0.24.2
         env:
         env:
         - name: TOKEN
         - name: TOKEN
           value: "TOKEN_VALUE"
           value: "TOKEN_VALUE"
         volumeMounts:
         volumeMounts:
         - mountPath: /etc/netclient
         - mountPath: /etc/netclient
           name: etc-netclient
           name: etc-netclient
+        - mountPath: /var/log
+          name: log-netclient
         securityContext:
         securityContext:
           privileged: true
           privileged: true
       volumes:
       volumes:
@@ -32,3 +34,6 @@ spec:
           path: /etc/netclient
           path: /etc/netclient
           type: DirectoryOrCreate
           type: DirectoryOrCreate
         name: etc-netclient
         name: etc-netclient
+      - emptyDir:
+          medium: Memory
+        name: log-netclient

+ 6 - 1
k8s/client/netclient.yaml

@@ -28,13 +28,15 @@ spec:
       #           - "<node label value>"
       #           - "<node label value>"
       containers:
       containers:
       - name: netclient
       - name: netclient
-        image: gravitl/netclient:v0.24.1
+        image: gravitl/netclient:v0.24.2
         env:
         env:
         - name: TOKEN
         - name: TOKEN
           value: "TOKEN_VALUE"
           value: "TOKEN_VALUE"
         volumeMounts:
         volumeMounts:
         - mountPath: /etc/netclient
         - mountPath: /etc/netclient
           name: etc-netclient
           name: etc-netclient
+        - mountPath: /var/log
+          name: log-netclient
         securityContext:
         securityContext:
           privileged: true
           privileged: true
       volumes:
       volumes:
@@ -42,3 +44,6 @@ spec:
           path: /etc/netclient
           path: /etc/netclient
           type: DirectoryOrCreate
           type: DirectoryOrCreate
         name: etc-netclient
         name: etc-netclient
+      - emptyDir:
+          medium: Memory
+        name: log-netclient

+ 1 - 1
k8s/server/netmaker-ui.yaml

@@ -15,7 +15,7 @@ spec:
     spec:
     spec:
       containers:
       containers:
       - name: netmaker-ui
       - name: netmaker-ui
-        image: gravitl/netmaker-ui:v0.24.1
+        image: gravitl/netmaker-ui:v0.24.2
         ports:
         ports:
         - containerPort: 443
         - containerPort: 443
         env:
         env:

+ 1 - 0
logic/gateway.go

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

+ 5 - 13
logic/hosts.go

@@ -217,7 +217,6 @@ func UpdateHost(newHost, currentHost *models.Host) {
 	newHost.Nodes = currentHost.Nodes
 	newHost.Nodes = currentHost.Nodes
 	newHost.PublicKey = currentHost.PublicKey
 	newHost.PublicKey = currentHost.PublicKey
 	newHost.TrafficKeyPublic = currentHost.TrafficKeyPublic
 	newHost.TrafficKeyPublic = currentHost.TrafficKeyPublic
-	newHost.EndpointIPv6 = currentHost.EndpointIPv6
 	// changeable fields
 	// changeable fields
 	if len(newHost.Version) == 0 {
 	if len(newHost.Version) == 0 {
 		newHost.Version = currentHost.Version
 		newHost.Version = currentHost.Version
@@ -397,20 +396,13 @@ func DissasociateNodeFromHost(n *models.Node, h *models.Host) error {
 	if len(h.Nodes) == 0 {
 	if len(h.Nodes) == 0 {
 		return fmt.Errorf("no nodes present in given host")
 		return fmt.Errorf("no nodes present in given host")
 	}
 	}
-	index := -1
+	nList := []string{}
 	for i := range h.Nodes {
 	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() {
 	go func() {
 		if servercfg.IsPro {
 		if servercfg.IsPro {
 			if clients, err := GetNetworkExtClients(n.Network); err != nil {
 			if clients, err := GetNetworkExtClients(n.Network); err != nil {
@@ -435,7 +427,7 @@ func DisassociateAllNodesFromHost(hostID string) error {
 	for _, nodeID := range host.Nodes {
 	for _, nodeID := range host.Nodes {
 		node, err := GetNodeByID(nodeID)
 		node, err := GetNodeByID(nodeID)
 		if err != nil {
 		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
 			continue
 		}
 		}
 		if err := DeleteNode(&node, true); err != nil {
 		if err := DeleteNode(&node, true); err != nil {

+ 1 - 1
main.go

@@ -27,7 +27,7 @@ import (
 	"golang.org/x/exp/slog"
 	"golang.org/x/exp/slog"
 )
 )
 
 
-var version = "v0.24.1"
+var version = "v0.24.2"
 
 
 // Start DB Connection and start API Request Handler
 // Start DB Connection and start API Request Handler
 func main() {
 func main() {

+ 2 - 0
models/structs.go

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

+ 1 - 0
mq/mq.go

@@ -129,6 +129,7 @@ func SetupMQTT(fatal bool) {
 
 
 // Keepalive -- periodically pings all nodes to let them know server is still alive and doing well
 // Keepalive -- periodically pings all nodes to let them know server is still alive and doing well
 func Keepalive(ctx context.Context) {
 func Keepalive(ctx context.Context) {
+	go PublishPeerUpdate(true)
 	for {
 	for {
 		select {
 		select {
 		case <-ctx.Done():
 		case <-ctx.Done():

+ 16 - 0
pro/controllers/users.go

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

+ 11 - 3
pro/logic/nodes.go

@@ -114,9 +114,13 @@ func UnsetInternetGw(node *models.Node) {
 
 
 func SetDefaultGwForRelayedUpdate(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
 func SetDefaultGwForRelayedUpdate(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
 	if relay.InternetGwID != "" {
 	if relay.InternetGwID != "" {
+		relayedHost, err := logic.GetHost(relayed.HostID.String())
+		if err != nil {
+			return peerUpdate
+		}
 		peerUpdate.ChangeDefaultGw = true
 		peerUpdate.ChangeDefaultGw = true
 		peerUpdate.DefaultGwIp = relay.Address.IP
 		peerUpdate.DefaultGwIp = relay.Address.IP
-		if peerUpdate.DefaultGwIp == nil {
+		if peerUpdate.DefaultGwIp == nil || relayedHost.EndpointIP == nil {
 			peerUpdate.DefaultGwIp = relay.Address6.IP
 			peerUpdate.DefaultGwIp = relay.Address6.IP
 		}
 		}
 
 
@@ -131,9 +135,14 @@ func SetDefaultGw(node models.Node, peerUpdate models.HostPeerUpdate) models.Hos
 		if err != nil {
 		if err != nil {
 			return peerUpdate
 			return peerUpdate
 		}
 		}
+		host, err := logic.GetHost(node.HostID.String())
+		if err != nil {
+			return peerUpdate
+		}
+
 		peerUpdate.ChangeDefaultGw = true
 		peerUpdate.ChangeDefaultGw = true
 		peerUpdate.DefaultGwIp = inetNode.Address.IP
 		peerUpdate.DefaultGwIp = inetNode.Address.IP
-		if peerUpdate.DefaultGwIp == nil {
+		if peerUpdate.DefaultGwIp == nil || host.EndpointIP == nil {
 			peerUpdate.DefaultGwIp = inetNode.Address6.IP
 			peerUpdate.DefaultGwIp = inetNode.Address6.IP
 		}
 		}
 	}
 	}
@@ -162,7 +171,6 @@ func GetAllowedIpForInetNodeClient(node, peer *models.Node) []net.IPNet {
 	if peer.Address.IP != nil {
 	if peer.Address.IP != nil {
 		_, ipnet, _ := net.ParseCIDR(IPv4Network)
 		_, ipnet, _ := net.ParseCIDR(IPv4Network)
 		allowedips = append(allowedips, *ipnet)
 		allowedips = append(allowedips, *ipnet)
-		return allowedips
 	}
 	}
 
 
 	if peer.Address6.IP != nil {
 	if peer.Address6.IP != nil {

+ 1 - 1
release.md

@@ -1,4 +1,4 @@
-# Netmaker v0.24.1
+# Netmaker v0.24.2
 
 
 ## Whats New ✨
 ## Whats New ✨
 - Users Can define Multiple Endpoints On The Remote Access Gateway To Choose From While Establishing a Connection.
 - Users Can define Multiple Endpoints On The Remote Access Gateway To Choose From While Establishing a Connection.

+ 1 - 1
swagger.yml

@@ -1472,7 +1472,7 @@ info:
 
 
         API calls must be authenticated via a header of the format -H “Authorization: Bearer <YOUR_SECRET_KEY>” There are two methods to obtain YOUR_SECRET_KEY: 1. Using the masterkey. By default, this value is “secret key,” but you should change this on your instance and keep it secure. This value can be set via env var at startup or in a config file (config/environments/< env >.yaml). See the [Netmaker](https://docs.netmaker.org/index.html) documentation for more details. 2. Using a JWT received for a node. This can be retrieved by calling the /api/nodes/<network>/authenticate endpoint, as documented below.
         API calls must be authenticated via a header of the format -H “Authorization: Bearer <YOUR_SECRET_KEY>” There are two methods to obtain YOUR_SECRET_KEY: 1. Using the masterkey. By default, this value is “secret key,” but you should change this on your instance and keep it secure. This value can be set via env var at startup or in a config file (config/environments/< env >.yaml). See the [Netmaker](https://docs.netmaker.org/index.html) documentation for more details. 2. Using a JWT received for a node. This can be retrieved by calling the /api/nodes/<network>/authenticate endpoint, as documented below.
     title: Netmaker
     title: Netmaker
-    version: 0.24.1
+    version: 0.24.2
 paths:
 paths:
     /api/dns:
     /api/dns:
         get:
         get: