Skip to content

Commit

Permalink
Merge pull request #2674 from gravitl/release-v0.21.2
Browse files Browse the repository at this point in the history
v0.21.2
  • Loading branch information
abhishek9686 authored Nov 19, 2023
2 parents 6aec0f6 + 7820d64 commit 5af7a6a
Show file tree
Hide file tree
Showing 41 changed files with 539 additions and 236 deletions.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ body:
label: Version
description: What version are you running?
options:
- v0.21.2
- v0.21.1
- v0.21.0
- v0.20.6
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

<p align="center">
<a href="https://github.com/gravitl/netmaker/releases">
<img src="https://img.shields.io/badge/Version-0.21.1-informational?style=flat-square" />
<img src="https://img.shields.io/badge/Version-0.21.2-informational?style=flat-square" />
</a>
<a href="https://hub.docker.com/r/gravitl/netmaker/tags">
<img src="https://img.shields.io/docker/pulls/gravitl/netmaker?label=downloads" />
Expand Down Expand Up @@ -57,7 +57,7 @@ These are the instructions for deploying a Netmaker server on your own cloud VM

1. Get a cloud VM with Ubuntu 22.04 and a public IP.
2. Open ports 443, 80, 3479, 8089 and 51821-51830/udp on the VM firewall and in cloud security settings.
3. (recommended) Prepare DNS - Set a wildcard subdomain in your DNS settings for Netmaker, e.g. *.netmaker.example.com, which points to your VM's pubic IP.
3. (recommended) Prepare DNS - Set a wildcard subdomain in your DNS settings for Netmaker, e.g. *.netmaker.example.com, which points to your VM's public IP.
4. Run the script:

`sudo wget -qO /root/nm-quick.sh https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/nm-quick.sh && sudo chmod +x /root/nm-quick.sh && sudo /root/nm-quick.sh`
Expand Down
13 changes: 11 additions & 2 deletions auth/host_session.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/mq"
"github.com/gravitl/netmaker/servercfg"
"golang.org/x/exp/slog"
)

// SessionHandler - called by the HTTP router when user
Expand Down Expand Up @@ -202,7 +203,7 @@ func SessionHandler(conn *websocket.Conn) {
if err = conn.WriteMessage(messageType, reponseData); err != nil {
logger.Log(0, "error during message writing:", err.Error())
}
go CheckNetRegAndHostUpdate(netsToAdd[:], &result.Host)
go CheckNetRegAndHostUpdate(netsToAdd[:], &result.Host, uuid.Nil)
case <-timeout: // the read from req.answerCh has timed out
if err = conn.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")); err != nil {
logger.Log(0, "error during timeout message writing:", err.Error())
Expand All @@ -221,7 +222,7 @@ func SessionHandler(conn *websocket.Conn) {
}

// CheckNetRegAndHostUpdate - run through networks and send a host update
func CheckNetRegAndHostUpdate(networks []string, h *models.Host) {
func CheckNetRegAndHostUpdate(networks []string, h *models.Host, relayNodeId uuid.UUID) {
// publish host update through MQ
for i := range networks {
network := networks[i]
Expand All @@ -231,6 +232,14 @@ func CheckNetRegAndHostUpdate(networks []string, h *models.Host) {
logger.Log(0, "failed to add host to network:", h.ID.String(), h.Name, network, err.Error())
continue
}
if relayNodeId != uuid.Nil && !newNode.IsRelayed {
newNode.IsRelayed = true
newNode.RelayedBy = relayNodeId.String()
slog.Info(fmt.Sprintf("adding relayed node %s to relay %s on network %s", newNode.ID.String(), relayNodeId.String(), network))
if err := logic.UpsertNode(newNode); err != nil {
slog.Error("failed to update node", "nodeid", relayNodeId.String())
}
}
logger.Log(1, "added new node", newNode.ID.String(), "to host", h.Name)
hostactions.AddAction(models.HostUpdate{
Action: models.JoinHostToNetwork,
Expand Down
2 changes: 1 addition & 1 deletion compose/docker-compose.netclient.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: "3.4"
services:
netclient:
container_name: netclient
image: 'gravitl/netclient:v0.21.1'
image: 'gravitl/netclient:v0.21.2'
hostname: netmaker-1
network_mode: host
restart: on-failure
Expand Down
2 changes: 1 addition & 1 deletion controllers/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//
// Schemes: https
// BasePath: /
// Version: 0.21.1
// Version: 0.21.2
// Host: api.demo.netmaker.io
//
// Consumes:
Expand Down
67 changes: 66 additions & 1 deletion controllers/enrollmentkeys.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http"
"time"

"github.com/google/uuid"
"github.com/gorilla/mux"

"github.com/gravitl/netmaker/auth"
Expand All @@ -26,6 +27,8 @@ func enrollmentKeyHandlers(r *mux.Router) {
Methods(http.MethodDelete)
r.HandleFunc("/api/v1/host/register/{token}", http.HandlerFunc(handleHostRegister)).
Methods(http.MethodPost)
r.HandleFunc("/api/v1/enrollment-keys/{keyID}", logic.SecurityCheck(true, http.HandlerFunc(updateEnrollmentKey))).
Methods(http.MethodPut)
}

// swagger:route GET /api/v1/enrollment-keys enrollmentKeys getEnrollmentKeys
Expand Down Expand Up @@ -113,12 +116,23 @@ func createEnrollmentKey(w http.ResponseWriter, r *http.Request) {
newTime = time.Unix(enrollmentKeyBody.Expiration, 0)
}

relayId := uuid.Nil
if enrollmentKeyBody.Relay != "" {
relayId, err = uuid.Parse(enrollmentKeyBody.Relay)
if err != nil {
logger.Log(0, r.Header.Get("user"), "error parsing relay id: ", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
}

newEnrollmentKey, err := logic.CreateEnrollmentKey(
enrollmentKeyBody.UsesRemaining,
newTime,
enrollmentKeyBody.Networks,
enrollmentKeyBody.Tags,
enrollmentKeyBody.Unlimited,
relayId,
)
if err != nil {
logger.Log(0, r.Header.Get("user"), "failed to create enrollment key:", err.Error())
Expand All @@ -136,6 +150,57 @@ func createEnrollmentKey(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(newEnrollmentKey)
}

// swagger:route PUT /api/v1/enrollment-keys/:id enrollmentKeys updateEnrollmentKey
//
// Updates an EnrollmentKey for hosts to use on Netmaker server. Updates only the relay to use.
//
// Schemes: https
//
// Security:
// oauth
//
// Responses:
// 200: EnrollmentKey
func updateEnrollmentKey(w http.ResponseWriter, r *http.Request) {
var enrollmentKeyBody models.APIEnrollmentKey
params := mux.Vars(r)
keyId := params["keyID"]

err := json.NewDecoder(r.Body).Decode(&enrollmentKeyBody)
if err != nil {
slog.Error("error decoding request body", "error", err)
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}

relayId := uuid.Nil
if enrollmentKeyBody.Relay != "" {
relayId, err = uuid.Parse(enrollmentKeyBody.Relay)
if err != nil {
slog.Error("error parsing relay id", "error", err)
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
}

newEnrollmentKey, err := logic.UpdateEnrollmentKey(keyId, relayId)
if err != nil {
slog.Error("failed to update enrollment key", "error", err)
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}

if err = logic.Tokenize(newEnrollmentKey, servercfg.GetAPIHost()); err != nil {
slog.Error("failed to update enrollment key", "error", err)
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}

slog.Info("updated enrollment key", "id", keyId)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(newEnrollmentKey)
}

// swagger:route POST /api/v1/enrollment-keys/{token} enrollmentKeys handleHostRegister
//
// Handles a Netclient registration with server and add nodes accordingly.
Expand Down Expand Up @@ -286,5 +351,5 @@ func handleHostRegister(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(&response)
// notify host of changes, peer and node updates
go auth.CheckNetRegAndHostUpdate(enrollmentKey.Networks, &newHost)
go auth.CheckNetRegAndHostUpdate(enrollmentKey.Networks, &newHost, enrollmentKey.Relay)
}
105 changes: 59 additions & 46 deletions controllers/hosts.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"

"github.com/gorilla/mux"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/logic"
"github.com/gravitl/netmaker/models"
Expand Down Expand Up @@ -123,11 +124,12 @@ func pull(w http.ResponseWriter, r *http.Request) {

serverConf.TrafficKey = key
response := models.HostPull{
Host: *host,
Nodes: logic.GetHostNodes(host),
ServerConfig: serverConf,
Peers: hPU.Peers,
PeerIDs: hPU.PeerIDs,
Host: *host,
Nodes: logic.GetHostNodes(host),
ServerConfig: serverConf,
Peers: hPU.Peers,
PeerIDs: hPU.PeerIDs,
HostNetworkInfo: hPU.HostNetworkInfo,
}

logger.Log(1, hostID, "completed a pull")
Expand Down Expand Up @@ -226,6 +228,19 @@ func deleteHost(w http.ResponseWriter, r *http.Request) {
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
for _, nodeID := range currHost.Nodes {
node, err := logic.GetNodeByID(nodeID)
if err != nil {
slog.Error("failed to get node", "nodeid", nodeID, "error", err)
continue
}
var gwClients []models.ExtClient
if node.IsIngressGateway {
gwClients = logic.GetGwExtclients(node.ID.String(), node.Network)
}
go mq.PublishMqUpdatesForDeletedNode(node, false, gwClients)

}
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"))
Expand Down Expand Up @@ -285,6 +300,7 @@ func addHostToNetwork(w http.ResponseWriter, r *http.Request) {
Node: *newNode,
})
mq.PublishPeerUpdate()
mq.HandleNewNodeDNS(currHost, newNode)
}()
logger.Log(2, r.Header.Get("user"), fmt.Sprintf("added host %s to network %s", currHost.Name, network))
w.WriteHeader(http.StatusOK)
Expand Down Expand Up @@ -314,65 +330,62 @@ func deleteHostFromNetwork(w http.ResponseWriter, r *http.Request) {
// confirm host exists
currHost, err := logic.GetHost(hostid)
if err != nil {
if database.IsEmptyRecord(err) {
// check if there is any daemon nodes that needs to be deleted
node, err := logic.GetNodeByHostRef(hostid, network)
if err != nil {
slog.Error("couldn't get node for host", "hostid", hostid, "network", network, "error", err)
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
if err = logic.DeleteNodeByID(&node); err != nil {
slog.Error("failed to force delete daemon node",
"nodeid", node.ID.String(), "hostid", hostid, "network", network, "error", err)
logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to force delete daemon node: "+err.Error()), "internal"))
return
}
logic.ReturnSuccessResponse(w, r, "force deleted daemon node successfully")
return
}

logger.Log(0, r.Header.Get("user"), "failed to find host:", err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}

node, err := logic.UpdateHostNetwork(currHost, network, false)
if err != nil {
if node == nil && forceDelete {
// force cleanup the node
node, err := logic.GetNodeByHostRef(hostid, network)
if err != nil {
slog.Error("couldn't get node for host", "hostid", hostid, "network", network, "error", err)
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
return
}
if err = logic.DeleteNodeByID(&node); err != nil {
slog.Error("failed to force delete daemon node",
"nodeid", node.ID.String(), "hostid", hostid, "network", network, "error", err)
logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to force delete daemon node: "+err.Error()), "internal"))
return
}
logic.ReturnSuccessResponse(w, r, "force deleted daemon node successfully")
return
}
logger.Log(0, r.Header.Get("user"), "failed to remove host from network:", hostid, network, err.Error())
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
return
}
if node.IsRelayed {
// cleanup node from relayednodes on relay node
relayNode, err := logic.GetNodeByID(node.RelayedBy)
if err == nil {
relayedNodes := []string{}
for _, relayedNodeID := range relayNode.RelayedNodes {
if relayedNodeID == node.ID.String() {
continue
}
relayedNodes = append(relayedNodes, relayedNodeID)
}
relayNode.RelayedNodes = relayedNodes
logic.UpsertNode(&relayNode)
}
}
if node.IsRelay {
// unset all the relayed nodes
logic.SetRelayedNodes(false, node.ID.String(), node.RelayedNodes)
}
var gwClients []models.ExtClient
if node.IsIngressGateway {
// delete ext clients belonging to ingress gateway
go func(node models.Node) {
if err = logic.DeleteGatewayExtClients(node.ID.String(), node.Network); err != nil {
slog.Error("failed to delete extclients", "gatewayid", node.ID.String(), "network", node.Network, "error", err.Error())
}
}(*node)
gwClients = logic.GetGwExtclients(node.ID.String(), node.Network)
}
logger.Log(1, "deleting node", node.ID.String(), "from host", currHost.Name)
if err := logic.DeleteNode(node, forceDelete); err != nil {
logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete node"), "internal"))
return
}
node.Action = models.NODE_DELETE
node.PendingDelete = true
go func() {
// notify node change
if err := mq.NodeUpdate(node); err != nil {
slog.Error("error publishing node update to node", "node", node.ID, "error", err)
}
// notify of peer change
err = mq.PublishDeletedNodePeerUpdate(node)
if err != nil {
logger.Log(1, "error publishing peer update ", err.Error())
}
if err := mq.PublishDNSDelete(node, currHost); err != nil {
logger.Log(1, "error publishing dns update", err.Error())
}
}()
go mq.PublishMqUpdatesForDeletedNode(*node, true, gwClients)
logger.Log(2, r.Header.Get("user"), fmt.Sprintf("removed host %s from network %s", currHost.Name, network))
w.WriteHeader(http.StatusOK)
}
Expand Down
Loading

0 comments on commit 5af7a6a

Please sign in to comment.