Browse Source

register host through server, add basic auth to turn apis

Abhishek Kondur 2 years ago
parent
commit
d4ceabd4b3

+ 56 - 0
logic/hosts.go

@@ -1,11 +1,15 @@
 package logic
 
 import (
+	"crypto/md5"
 	"encoding/json"
 	"errors"
 	"fmt"
 	"log"
+	"net/http"
+	"strconv"
 
+	"github.com/devilcove/httpclient"
 	"github.com/google/uuid"
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/logger"
@@ -201,11 +205,13 @@ func RemoveHost(h *models.Host) error {
 	if len(h.Nodes) > 0 {
 		return fmt.Errorf("host still has associated nodes")
 	}
+	DeRegisterHostWithTurn(h.ID.String())
 	return database.DeleteRecord(database.HOSTS_TABLE_NAME, h.ID.String())
 }
 
 // RemoveHostByID - removes a given host by id from server
 func RemoveHostByID(hostID string) error {
+	DeRegisterHostWithTurn(hostID)
 	return database.DeleteRecord(database.HOSTS_TABLE_NAME, hostID)
 }
 
@@ -428,3 +434,53 @@ func GetHostByNodeID(id string) *models.Host {
 	}
 	return nil
 }
+
+// ConvHostPassToHash - converts password to md5 hash
+func ConvHostPassToHash(hostPass string) string {
+	return fmt.Sprintf("%x", md5.Sum([]byte(hostPass)))
+}
+
+// RegisterHostWithTurn - registers the host with the given turn server
+func RegisterHostWithTurn(hostID, hostPass string) error {
+
+	api := httpclient.JSONEndpoint[models.SuccessResponse, models.ErrorResponse]{
+		URL:    servercfg.GetTurnApiHost(),
+		Route:  "/api/v1/host/register",
+		Method: http.MethodPost,
+		//Authorization: fmt.Sprintf("Bearer %s", op.AuthToken),
+		Data: models.HostTurnRegister{
+			HostID:       hostID,
+			HostPassHash: ConvHostPassToHash(hostPass),
+		},
+		Response:      models.SuccessResponse{},
+		ErrorResponse: models.ErrorResponse{},
+	}
+	_, errData, err := api.GetJSON(models.SuccessResponse{}, models.ErrorResponse{})
+	if err != nil {
+		if errors.Is(err, httpclient.ErrStatus) {
+			logger.Log(1, "error server status", strconv.Itoa(errData.Code), errData.Message)
+		}
+		return err
+	}
+	return nil
+}
+
+// DeRegisterHostWithTurn - to be called when host need to be deregistered from a turn server
+func DeRegisterHostWithTurn(hostID string) error {
+
+	api := httpclient.JSONEndpoint[models.SuccessResponse, models.ErrorResponse]{
+		URL:           servercfg.GetTurnApiHost(),
+		Route:         fmt.Sprintf("/api/v1/host/deregister?host_id=%s", hostID),
+		Method:        http.MethodPost,
+		Response:      models.SuccessResponse{},
+		ErrorResponse: models.ErrorResponse{},
+	}
+	_, errData, err := api.GetJSON(models.SuccessResponse{}, models.ErrorResponse{})
+	if err != nil {
+		if errors.Is(err, httpclient.ErrStatus) {
+			logger.Log(1, "error server status", strconv.Itoa(errData.Code), errData.Message)
+		}
+		return err
+	}
+	return nil
+}

+ 2 - 0
models/host.go

@@ -116,6 +116,8 @@ const (
 	RequestAck = "REQ_ACK"
 	// CheckIn - update last check in times and public address and interfaces
 	CheckIn = "CHECK_IN"
+	// REGISTER_WITH_TURN - registers host with turn server if configured
+	RegisterWithTurn = "REGISTER_WITH_TURN"
 )
 
 // HostUpdate - struct for host update

+ 2 - 0
mq/handlers.go

@@ -140,6 +140,8 @@ func UpdateHost(client mqtt.Client, msg mqtt.Message) {
 			return
 		}
 		sendPeerUpdate = true
+	case models.RegisterWithTurn:
+		logic.RegisterHostWithTurn(hostUpdate.Host.ID.String(), hostUpdate.Host.HostPass)
 	}
 
 	if sendPeerUpdate {

+ 10 - 0
turnserver/config/config.go

@@ -87,3 +87,13 @@ func GetAPIPort() int {
 	}
 	return apiport
 }
+
+// GetUserName - gets the username for the apis
+func GetUserName() string {
+	return os.Getenv("USERNAME")
+}
+
+// GetPassword - gets the password for the server apis
+func GetPassword() string {
+	return os.Getenv("PASSWORD")
+}

+ 1 - 1
turnserver/internal/host/host.go

@@ -35,5 +35,5 @@ func Remove(c *gin.Context) {
 		return
 	}
 	utils.ReturnSuccessResponse(c,
-		fmt.Sprintf("unregistred host (%s) successfully", hostID), nil)
+		fmt.Sprintf("unregistered host (%s) successfully", hostID), nil)
 }

+ 3 - 5
turnserver/main.go

@@ -15,16 +15,14 @@ import (
 func main() {
 	ctx, cancel := context.WithCancel(context.Background())
 	wg := &sync.WaitGroup{}
-	// Wait for interrupt signal to gracefully shutdown the server with
-	// a timeout of 5 seconds.
 	quit := make(chan os.Signal, 2)
-	// kill (no param) default send syscanll.SIGTERM
-	// kill -2 is syscall.SIGINT
-	// kill -9 is syscall. SIGKILL but cant be caught, so don't need add it
 	wg.Add(1)
 	go controller.HandleRESTRequests(ctx, wg)
 	wg.Add(1)
 	go turn.Start(ctx, wg)
+	// kill (no param) default send syscanll.SIGTERM
+	// kill -2 is syscall.SIGINT
+	// kill -9 is syscall. SIGKILL but cant be caught, so don't need add it
 	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
 	<-quit
 	logger.Log(0, "Recieved Shutdown Signal...")

+ 10 - 3
turnserver/src/routes/routes.go

@@ -4,6 +4,7 @@ import (
 	"net/http"
 
 	"github.com/gin-gonic/gin"
+	"github.com/gravitl/netmaker/turnserver/config"
 	"github.com/gravitl/netmaker/turnserver/internal/host"
 )
 
@@ -15,9 +16,15 @@ func Init(r *gin.Engine) *gin.Engine {
 }
 
 func registerRoutes(r *gin.RouterGroup) {
-	r.POST("/host/register", host.Register)
-	r.DELETE("/host/deregister", host.Remove)
-	r.GET("/status", status)
+	r.POST("/host/register", gin.BasicAuth(gin.Accounts{
+		config.GetUserName(): config.GetPassword(),
+	}), host.Register)
+	r.DELETE("/host/deregister", gin.BasicAuth(gin.Accounts{
+		config.GetUserName(): config.GetPassword(),
+	}), host.Remove)
+	r.GET("/status", gin.BasicAuth(gin.Accounts{
+		config.GetUserName(): config.GetPassword(),
+	}), status)
 }
 
 func status(c *gin.Context) {