Ver Fonte

setup api handlers for egress revamp

abhishek9686 há 5 meses atrás
pai
commit
7579da93e2
11 ficheiros alterados com 234 adições e 22 exclusões
  1. 1 0
      controllers/controller.go
  2. 158 5
      controllers/egress.go
  3. 1 1
      controllers/migrate.go
  4. 1 1
      controllers/tags.go
  5. 1 1
      logic/auth.go
  6. 21 0
      logic/egress.go
  7. 1 1
      logic/gateway.go
  8. 2 2
      logic/jwts.go
  9. 1 1
      logic/tags.go
  10. 44 7
      models/egress.go
  11. 3 3
      models/node.go

+ 1 - 0
controllers/controller.go

@@ -37,6 +37,7 @@ var HttpHandlers = []interface{}{
 	enrollmentKeyHandlers,
 	tagHandlers,
 	aclHandlers,
+	egressHandlers,
 	legacyHandlers,
 }
 

+ 158 - 5
controllers/egress.go

@@ -1,10 +1,163 @@
 package controller
 
-import "github.com/gorilla/mux"
+import (
+	"encoding/json"
+	"errors"
+	"net/http"
+	"time"
+
+	"github.com/google/uuid"
+	"github.com/gorilla/mux"
+	"github.com/gravitl/netmaker/logger"
+	"github.com/gravitl/netmaker/logic"
+	"github.com/gravitl/netmaker/models"
+)
 
 func egressHandlers(r *mux.Router) {
-	/*
-	   1. Define Model
-	   2.
-	*/
+	r.HandleFunc("/api/v1/egress", logic.SecurityCheck(true, http.HandlerFunc(createEgress))).Methods(http.MethodPost)
+	r.HandleFunc("/api/v1/egress", logic.SecurityCheck(true, http.HandlerFunc(listEgress))).Methods(http.MethodGet)
+	r.HandleFunc("/api/v1/egress", logic.SecurityCheck(true, http.HandlerFunc(updateEgress))).Methods(http.MethodPut)
+	r.HandleFunc("/api/v1/egress", logic.SecurityCheck(true, http.HandlerFunc(deleteEgress))).Methods(http.MethodDelete)
+}
+
+// @Summary     Create Egress Resource
+// @Router      /api/v1/egress [post]
+// @Tags        Auth
+// @Accept      json
+// @Param       body body models.Egress
+// @Success     200 {object} models.SuccessResponse
+// @Failure     400 {object} models.ErrorResponse
+// @Failure     401 {object} models.ErrorResponse
+// @Failure     500 {object} models.ErrorResponse
+func createEgress(w http.ResponseWriter, r *http.Request) {
+
+	var req models.Egress
+	err := json.NewDecoder(r.Body).Decode(&req)
+	if err != nil {
+		logger.Log(0, "error decoding request body: ",
+			err.Error())
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+
+	if !logic.ValidateEgressReq(&req) {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid egress request"), "badrequest"))
+		return
+	}
+	req.ID = uuid.New().String()
+	req.CreatedBy = r.Header.Get("user")
+	req.CreatedAt = time.Now().UTC()
+	err = req.Create()
+	if err != nil {
+		logic.ReturnErrorResponse(
+			w,
+			r,
+			logic.FormatError(errors.New("error creating egress resource"+err.Error()), "internal"),
+		)
+		return
+	}
+	logic.ReturnSuccessResponseWithJson(w, r, req, "created egress resource")
+}
+
+// @Summary     List Egress Resource
+// @Router      /api/v1/egress [get]
+// @Tags        Auth
+// @Accept      json
+// @Param       query network string
+// @Success     200 {object} models.SuccessResponse
+// @Failure     400 {object} models.ErrorResponse
+// @Failure     401 {object} models.ErrorResponse
+// @Failure     500 {object} models.ErrorResponse
+func listEgress(w http.ResponseWriter, r *http.Request) {
+
+	network := r.URL.Query().Get("network")
+	if network == "" {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("username is required"), "badrequest"))
+		return
+	}
+	e := models.Egress{Network: network}
+	list, err := e.ListByNetwork()
+	if err != nil {
+		logic.ReturnErrorResponse(
+			w,
+			r,
+			logic.FormatError(errors.New("error creating egress resource"+err.Error()), "internal"),
+		)
+		return
+	}
+	logic.ReturnSuccessResponseWithJson(w, r, list, "fetched egress resource list")
+}
+
+// @Summary     Update Egress Resource
+// @Router      /api/v1/egress [put]
+// @Tags        Auth
+// @Accept      json
+// @Param       body body models.Egress
+// @Success     200 {object} models.SuccessResponse
+// @Failure     400 {object} models.ErrorResponse
+// @Failure     401 {object} models.ErrorResponse
+// @Failure     500 {object} models.ErrorResponse
+func updateEgress(w http.ResponseWriter, r *http.Request) {
+
+	var req models.Egress
+	err := json.NewDecoder(r.Body).Decode(&req)
+	if err != nil {
+		logger.Log(0, "error decoding request body: ",
+			err.Error())
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	e := models.Egress{ID: req.ID}
+	err = e.Get()
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	e.Nodes = req.Nodes
+	e.Tags = req.Tags
+	e.Range = req.Range
+	e.Description = req.Description
+	e.UpdatedAt = time.Now().UTC()
+	if !logic.ValidateEgressReq(&req) {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid egress request"), "badrequest"))
+		return
+	}
+	err = e.Update()
+	if err != nil {
+		logic.ReturnErrorResponse(
+			w,
+			r,
+			logic.FormatError(errors.New("error creating egress resource"+err.Error()), "internal"),
+		)
+		return
+	}
+	logic.ReturnSuccessResponseWithJson(w, r, req, "updated egress resource")
+}
+
+// @Summary     Delete Egress Resource
+// @Router      /api/v1/egress [delete]
+// @Tags        Auth
+// @Accept      json
+// @Param       body body models.Egress
+// @Success     200 {object} models.SuccessResponse
+// @Failure     400 {object} models.ErrorResponse
+// @Failure     401 {object} models.ErrorResponse
+// @Failure     500 {object} models.ErrorResponse
+func deleteEgress(w http.ResponseWriter, r *http.Request) {
+
+	var req models.Egress
+	err := json.NewDecoder(r.Body).Decode(&req)
+	if err != nil {
+		logger.Log(0, "error decoding request body: ",
+			err.Error())
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	e := models.Egress{ID: req.ID}
+	err = e.Delete()
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+	logic.ReturnSuccessResponseWithJson(w, r, nil, "deleted egress resource")
 }

+ 1 - 1
controllers/migrate.go

@@ -208,7 +208,7 @@ func convertLegacyNode(legacy models.LegacyNode, hostID uuid.UUID) models.Node {
 	node.IsRelay = false
 	node.RelayedNodes = []string{}
 	node.DNSOn = models.ParseBool(legacy.DNSOn)
-	node.LastModified = time.Now()
+	node.LastModified = time.Now().UTC()
 	node.ExpirationDateTime = time.Unix(legacy.ExpirationDateTime, 0)
 	node.EgressGatewayNatEnabled = models.ParseBool(legacy.EgressGatewayNatEnabled)
 	node.EgressGatewayRequest = legacy.EgressGatewayRequest

+ 1 - 1
controllers/tags.go

@@ -89,7 +89,7 @@ func createTag(w http.ResponseWriter, r *http.Request) {
 		Network:   req.Network,
 		CreatedBy: user.UserName,
 		ColorCode: req.ColorCode,
-		CreatedAt: time.Now(),
+		CreatedAt: time.Now().UTC(),
 	}
 	_, err = logic.GetTag(tag.ID)
 	if err == nil {

+ 1 - 1
logic/auth.go

@@ -235,7 +235,7 @@ func VerifyAuthRequest(authRequest models.UserAuthParams) (string, error) {
 	}
 
 	// update last login time
-	result.LastLoginTime = time.Now()
+	result.LastLoginTime = time.Now().UTC()
 	err = UpsertUser(result)
 	if err != nil {
 		slog.Error("error upserting user", "error", err)

+ 21 - 0
logic/egress.go

@@ -0,0 +1,21 @@
+package logic
+
+import "github.com/gravitl/netmaker/models"
+
+func ValidateEgressReq(e *models.Egress) bool {
+	if e.Network == "" {
+		return false
+	}
+	if e.Range.IP == nil {
+		return false
+	}
+	if len(e.Nodes) != 0 {
+		for _, nodeID := range e.Nodes {
+			_, err := GetNodeByID(nodeID)
+			if err != nil {
+				return false
+			}
+		}
+	}
+	return true
+}

+ 1 - 1
logic/gateway.go

@@ -267,7 +267,7 @@ func DeleteIngressGateway(nodeid string) (models.Node, []models.ExtClient, error
 		return models.Node{}, removedClients, err
 	}
 	logger.Log(3, "deleting ingress gateway")
-	node.LastModified = time.Now()
+	node.LastModified = time.Now().UTC()
 	node.IsIngressGateway = false
 	if !servercfg.IsPro {
 		node.IsInternetGateway = false

+ 2 - 2
logic/jwts.go

@@ -131,7 +131,7 @@ func GetUserNameFromToken(authtoken string) (username string, err error) {
 				err = errors.New("token revoked")
 				return "", err
 			}
-			a.LastUsed = time.Now()
+			a.LastUsed = time.Now().UTC()
 			a.Update()
 		}
 	}
@@ -175,7 +175,7 @@ func VerifyUserToken(tokenString string) (username string, issuperadmin, isadmin
 				err = errors.New("token revoked")
 				return "", false, false, err
 			}
-			a.LastUsed = time.Now()
+			a.LastUsed = time.Now().UTC()
 			a.Update()
 		}
 	}

+ 1 - 1
logic/tags.go

@@ -290,7 +290,7 @@ func CreateDefaultTags(netID models.NetworkID) {
 		TagName:   models.GwTagName,
 		Network:   netID,
 		CreatedBy: "auto",
-		CreatedAt: time.Now(),
+		CreatedAt: time.Now().UTC(),
 	}
 	_, err := GetTag(tag.ID)
 	if err == nil {

+ 44 - 7
models/egress.go

@@ -1,12 +1,49 @@
 package models
 
-import "net"
+import (
+	"context"
+	"net"
+	"time"
+
+	"github.com/gravitl/netmaker/db"
+)
+
+const egressTable = "egress"
 
 type Egress struct {
-	ID          string    `json:"id"`
-	Name        string    `json:"name"`
-	Description string    `json:"description"`
-	EgressNode  string    `json:"egress_node"`
-	EgressGroup []TagID   `json:"egress_group"`
-	Range       net.IPNet `json:"range"`
+	ID          string    `gorm:"id,primary_key" json:"id"`
+	Name        string    `gorm:"name" json:"name"`
+	Network     string    `gorm:"network" json:"network"`
+	Description string    `gorm:"description" json:"description"`
+	Nodes       []string  `gorm:"nodes" json:"nodes"`
+	Tags        []TagID   `gorm:"tags" json:"tags"`
+	Range       net.IPNet `gorm:"range" json:"range"`
+	CreatedBy   string    `json:"created_by"`
+	CreatedAt   time.Time `json:"created_at"`
+	UpdatedAt   time.Time `json:"updated_at"`
+}
+
+func (e *Egress) Table() string {
+	return egressTable
+}
+
+func (e *Egress) Get() error {
+	return db.FromContext(context.TODO()).Table(e.Table()).First(&e).Where("id = ?", e.ID).Error
+}
+
+func (e *Egress) Update() error {
+	return db.FromContext(context.TODO()).Table(e.Table()).Where("id = ?", e.ID).Updates(&e).Error
+}
+
+func (e *Egress) Create() error {
+	return db.FromContext(context.TODO()).Table(e.Table()).Create(&e).Error
+}
+
+func (e *Egress) ListByNetwork() (egs []Egress, err error) {
+	err = db.FromContext(context.TODO()).Table(e.Table()).Where("network = ?", e.Network).Find(&egs).Error
+	return
+}
+
+func (e *Egress) Delete() error {
+	return db.FromContext(context.TODO()).Table(e.Table()).Where("id = ?", e.ID).Delete(&e).Error
 }

+ 3 - 3
models/node.go

@@ -377,17 +377,17 @@ func (node *LegacyNode) SetIsStaticDefault() {
 
 // Node.SetLastModified - set last modified initial time
 func (node *Node) SetLastModified() {
-	node.LastModified = time.Now()
+	node.LastModified = time.Now().UTC()
 }
 
 // Node.SetLastCheckIn - set checkin time of node
 func (node *Node) SetLastCheckIn() {
-	node.LastCheckIn = time.Now()
+	node.LastCheckIn = time.Now().UTC()
 }
 
 // Node.SetLastPeerUpdate - sets last peer update time
 func (node *Node) SetLastPeerUpdate() {
-	node.LastPeerUpdate = time.Now()
+	node.LastPeerUpdate = time.Now().UTC()
 }
 
 // Node.SetExpirationDateTime - sets node expiry time