abhishek9686 преди 11 месеца
родител
ревизия
6bc59adb2c
променени са 4 файла, в които са добавени 201 реда и са изтрити 7 реда
  1. 150 0
      controllers/acls.go
  2. 1 0
      controllers/controller.go
  3. 46 7
      logic/acls.go
  4. 4 0
      models/acl.go

+ 150 - 0
controllers/acls.go

@@ -0,0 +1,150 @@
+package controller
+
+import (
+	"encoding/json"
+	"errors"
+	"net/http"
+	"net/url"
+	"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 aclHandlers(r *mux.Router) {
+	r.HandleFunc("/api/v1/acls", logic.SecurityCheck(true, http.HandlerFunc(getAcls))).
+		Methods(http.MethodGet)
+	r.HandleFunc("/api/v1/acls", logic.SecurityCheck(true, http.HandlerFunc(createAcl))).
+		Methods(http.MethodPost)
+	r.HandleFunc("/api/v1/acls", logic.SecurityCheck(true, http.HandlerFunc(updateAcl))).
+		Methods(http.MethodPut)
+	r.HandleFunc("/api/v1/acls", logic.SecurityCheck(true, http.HandlerFunc(deleteAcl))).
+		Methods(http.MethodDelete)
+
+}
+
+// @Summary     List Acls in a network
+// @Router      /api/v1/acls [get]
+// @Tags        ACL
+// @Accept      json
+// @Success     200 {array} models.SuccessResponse
+// @Failure     500 {object} models.ErrorResponse
+func getAcls(w http.ResponseWriter, r *http.Request) {
+	netID, _ := url.QueryUnescape(r.URL.Query().Get("network"))
+	if netID == "" {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("network id param is missing"), "badrequest"))
+		return
+	}
+	// check if network exists
+	_, err := logic.GetNetwork(netID)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	acls, err := logic.ListAcls(models.NetworkID(netID))
+	if err != nil {
+		logger.Log(0, r.Header.Get("user"), "failed to get all network acl entries: ", err.Error())
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+	logic.SortAclEntrys(acls[:])
+	logic.ReturnSuccessResponseWithJson(w, r, acls, "fetched all acls in the network "+netID)
+}
+
+// @Summary     Create Acl
+// @Router      /api/v1/acls [post]
+// @Tags        ACL
+// @Accept      json
+// @Success     200 {array} models.SuccessResponse
+// @Failure     500 {object} models.ErrorResponse
+func createAcl(w http.ResponseWriter, r *http.Request) {
+	var req models.Acl
+	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
+	}
+	user, err := logic.GetUser(r.Header.Get("user"))
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	// check if acl network exists
+	_, err = logic.GetNetwork(req.NetworkID.String())
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to get network details for "+req.NetworkID.String()), "badrequest"))
+		return
+	}
+	// check if acl exists
+	acl := req
+	acl.ID = uuid.New()
+	acl.CreatedBy = user.UserName
+	acl.CreatedAt = time.Now().UTC()
+
+	err = logic.InsertAcl(acl)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+
+	logic.ReturnSuccessResponseWithJson(w, r, req, "created acl successfully")
+}
+
+// @Summary     Update Acl
+// @Router      /api/v1/acls [put]
+// @Tags        ACL
+// @Accept      json
+// @Success     200 {array} models.SuccessResponse
+// @Failure     500 {object} models.ErrorResponse
+func updateAcl(w http.ResponseWriter, r *http.Request) {
+	var updateAcl models.Acl
+	err := json.NewDecoder(r.Body).Decode(&updateAcl)
+	if err != nil {
+		logger.Log(0, "error decoding request body: ",
+			err.Error())
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+
+	acl, err := logic.GetAcl(updateAcl.ID.String())
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	err = logic.UpdateAcl(updateAcl, acl)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	logic.ReturnSuccessResponse(w, r, "updated acl "+updateAcl.Name)
+}
+
+// @Summary     Delete Acl
+// @Router      /api/v1/acls [delete]
+// @Tags        ACL
+// @Accept      json
+// @Success     200 {array} models.SuccessResponse
+// @Failure     500 {object} models.ErrorResponse
+func deleteAcl(w http.ResponseWriter, r *http.Request) {
+	aclID, _ := url.QueryUnescape(r.URL.Query().Get("acl_id"))
+	if aclID == "" {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("acl id is required"), "badrequest"))
+		return
+	}
+	acl, err := logic.GetAcl(aclID)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	err = logic.DeleteAcl(acl)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+	logic.ReturnSuccessResponse(w, r, "deleted acl "+acl.Name)
+}

+ 1 - 0
controllers/controller.go

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

+ 46 - 7
logic/acls.go

@@ -2,13 +2,14 @@ package logic
 
 import (
 	"encoding/json"
+	"sort"
 
 	"github.com/gravitl/netmaker/database"
 	"github.com/gravitl/netmaker/models"
 )
 
-// Create - creates acl policy
-func Create(a models.Acl) error {
+// InsertAcl - creates acl policy
+func InsertAcl(a models.Acl) error {
 	d, err := json.Marshal(a)
 	if err != nil {
 		return err
@@ -16,13 +17,42 @@ func Create(a models.Acl) error {
 	return database.Insert(a.ID.String(), string(d), database.ACLS_TABLE_NAME)
 }
 
-// Delete - deletes acl policy
-func Delete(a models.Acl) error {
+func GetAcl(aID string) (models.Acl, error) {
+	a := models.Acl{}
+	d, err := database.FetchRecord(database.ACLS_TABLE_NAME, aID)
+	if err != nil {
+		return a, err
+	}
+	err = json.Unmarshal([]byte(d), &a)
+	if err != nil {
+		return a, err
+	}
+	return a, nil
+}
+
+// UpdateAcl - updates allowed fields on acls and commits to DB
+func UpdateAcl(newAcl, acl models.Acl) error {
+	if newAcl.Name != "" {
+		acl.Name = newAcl.Name
+	}
+	acl.Src = newAcl.Src
+	acl.Dst = newAcl.Dst
+	acl.AllowedDirection = newAcl.AllowedDirection
+	acl.Enabled = newAcl.Enabled
+	d, err := json.Marshal(acl)
+	if err != nil {
+		return err
+	}
+	return database.Insert(acl.ID.String(), string(d), database.ACLS_TABLE_NAME)
+}
+
+// DeleteAcl - deletes acl policy
+func DeleteAcl(a models.Acl) error {
 	return database.DeleteRecord(database.ACLS_TABLE_NAME, a.ID.String())
 }
 
-// List - lists all acl policies
-func List(a models.Acl) ([]models.Acl, error) {
+// ListAcls - lists all acl policies
+func ListAcls(netID models.NetworkID) ([]models.Acl, error) {
 	data, err := database.FetchRecords(database.TAG_TABLE_NAME)
 	if err != nil && !database.IsEmptyRecord(err) {
 		return []models.Acl{}, err
@@ -34,7 +64,16 @@ func List(a models.Acl) ([]models.Acl, error) {
 		if err != nil {
 			continue
 		}
-		acls = append(acls, acl)
+		if acl.NetworkID == netID {
+			acls = append(acls, acl)
+		}
 	}
 	return acls, nil
 }
+
+// SortTagEntrys - Sorts slice of Tag entries by their id
+func SortAclEntrys(acls []models.Acl) {
+	sort.Slice(acls, func(i, j int) bool {
+		return acls[i].Name < acls[j].Name
+	})
+}

+ 4 - 0
models/acl.go

@@ -1,6 +1,8 @@
 package models
 
 import (
+	"time"
+
 	"github.com/google/uuid"
 )
 
@@ -30,4 +32,6 @@ type Acl struct {
 	Dst              []string                `json:"dst_type"`
 	AllowedDirection AllowedTrafficDirection `json:"allowed_traffic_direction"`
 	Enabled          bool                    `json:"enabled"`
+	CreatedBy        string                  `json:"created_by"`
+	CreatedAt        time.Time               `json:"created_at"`
 }