register host through server, add basic auth to turn apis

This commit is contained in:
Abhishek Kondur 2023-04-17 11:21:28 +04:00
parent 7a5e7976f4
commit d4ceabd4b3
7 changed files with 84 additions and 9 deletions

View file

@ -1,11 +1,15 @@
package logic package logic
import ( import (
"crypto/md5"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"log" "log"
"net/http"
"strconv"
"github.com/devilcove/httpclient"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/gravitl/netmaker/database" "github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logger"
@ -201,11 +205,13 @@ func RemoveHost(h *models.Host) error {
if len(h.Nodes) > 0 { if len(h.Nodes) > 0 {
return fmt.Errorf("host still has associated nodes") return fmt.Errorf("host still has associated nodes")
} }
DeRegisterHostWithTurn(h.ID.String())
return database.DeleteRecord(database.HOSTS_TABLE_NAME, h.ID.String()) return database.DeleteRecord(database.HOSTS_TABLE_NAME, h.ID.String())
} }
// RemoveHostByID - removes a given host by id from server // RemoveHostByID - removes a given host by id from server
func RemoveHostByID(hostID string) error { func RemoveHostByID(hostID string) error {
DeRegisterHostWithTurn(hostID)
return database.DeleteRecord(database.HOSTS_TABLE_NAME, hostID) return database.DeleteRecord(database.HOSTS_TABLE_NAME, hostID)
} }
@ -428,3 +434,53 @@ func GetHostByNodeID(id string) *models.Host {
} }
return nil 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
}

View file

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

View file

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

View file

@ -87,3 +87,13 @@ func GetAPIPort() int {
} }
return apiport 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")
}

View file

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

View file

@ -15,16 +15,14 @@ import (
func main() { func main() {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
// Wait for interrupt signal to gracefully shutdown the server with
// a timeout of 5 seconds.
quit := make(chan os.Signal, 2) 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) wg.Add(1)
go controller.HandleRESTRequests(ctx, wg) go controller.HandleRESTRequests(ctx, wg)
wg.Add(1) wg.Add(1)
go turn.Start(ctx, wg) 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) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit <-quit
logger.Log(0, "Recieved Shutdown Signal...") logger.Log(0, "Recieved Shutdown Signal...")

View file

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