From 9deac0ad2dff4be04e6a2d164d42dbe86788abc1 Mon Sep 17 00:00:00 2001 From: abhishek9686 Date: Sat, 28 Sep 2024 17:19:01 +0400 Subject: [PATCH] sync tag updates with acl policies --- controllers/acls.go | 21 ++++++++++---- controllers/tags.go | 21 ++++++++++++-- logic/acls.go | 71 ++++++++++++++++++++++++++++++++++++++++++--- logic/tags.go | 2 ++ 4 files changed, 102 insertions(+), 13 deletions(-) diff --git a/controllers/acls.go b/controllers/acls.go index ae657ca8..5574968a 100644 --- a/controllers/acls.go +++ b/controllers/acls.go @@ -35,7 +35,20 @@ func aclHandlers(r *mux.Router) { // @Success 200 {array} models.SuccessResponse // @Failure 500 {object} models.ErrorResponse func getAclPolicyTypes(w http.ResponseWriter, r *http.Request) { - logic.ReturnSuccessResponseWithJson(w, r, nil, "fetched all acls in the network ") + nodeID, _ := url.QueryUnescape(r.URL.Query().Get("node")) + peerID, _ := url.QueryUnescape(r.URL.Query().Get("peer")) + node, err := logic.GetNodeByID(nodeID) + if err != nil { + logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) + return + } + peer, err := logic.GetNodeByID(peerID) + if err != nil { + logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) + return + } + allowed := logic.IsNodeAllowedToCommunicate(node, peer) + logic.ReturnSuccessResponseWithJson(w, r, allowed, "fetched all acls in the network ") } // @Summary List Acls in a network @@ -142,10 +155,6 @@ func updateAcl(w http.ResponseWriter, r *http.Request) { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) return } - if acl.Default { - logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot update default policy"), "badrequest")) - return - } if !logic.IsAclPolicyValid(updateAcl.Acl) { logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid policy"), "badrequest")) return @@ -154,7 +163,7 @@ func updateAcl(w http.ResponseWriter, r *http.Request) { logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid policy, network id mismatch"), "badrequest")) return } - if updateAcl.NewName != "" { + if !acl.Default && updateAcl.NewName != "" { //check if policy exists with same name id := models.FormatAclID(updateAcl.NetworkID, updateAcl.NewName) _, err := logic.GetAcl(id) diff --git a/controllers/tags.go b/controllers/tags.go index 238611c8..837cc603 100644 --- a/controllers/tags.go +++ b/controllers/tags.go @@ -13,6 +13,7 @@ import ( "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/models" + "github.com/gravitl/netmaker/mq" ) func tagHandlers(r *mux.Router) { @@ -107,7 +108,7 @@ func createTag(w http.ResponseWriter, r *http.Request) { logic.UpsertNode(&node) } }() - + go mq.PublishPeerUpdate(false) logic.ReturnSuccessResponseWithJson(w, r, req, "created tag successfully") } @@ -146,7 +147,11 @@ func updateTag(w http.ResponseWriter, r *http.Request) { // delete old Tag entry logic.DeleteTag(updateTag.ID) } - go logic.UpdateTag(updateTag, newID) + go func() { + logic.UpdateTag(updateTag, newID) + logic.UpdateDeviceTag(updateTag.ID, newID, tag.Network) + mq.PublishPeerUpdate(false) + }() logic.ReturnSuccessResponse(w, r, "updating tags") } @@ -162,10 +167,20 @@ func deleteTag(w http.ResponseWriter, r *http.Request) { logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest")) return } - err := logic.DeleteTag(models.TagID(tagID)) + tag, err := logic.GetTag(models.TagID(tagID)) if err != nil { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest")) return } + err = logic.DeleteTag(models.TagID(tagID)) + if err != nil { + logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) + return + } + + go func() { + logic.RemoveDeviceTagFromAclPolicies(tag.ID, tag.Network) + mq.PublishPeerUpdate(false) + }() logic.ReturnSuccessResponse(w, r, "deleted tag "+tagID) } diff --git a/logic/acls.go b/logic/acls.go index 2ad042c0..3372453d 100644 --- a/logic/acls.go +++ b/logic/acls.go @@ -198,9 +198,11 @@ func IsAclPolicyValid(acl models.Acl) bool { // UpdateAcl - updates allowed fields on acls and commits to DB func UpdateAcl(newAcl, acl models.Acl) error { - acl.Name = newAcl.Name - acl.Src = newAcl.Src - acl.Dst = newAcl.Dst + if !acl.Default { + acl.Name = newAcl.Name + acl.Src = newAcl.Src + acl.Dst = newAcl.Dst + } acl.Enabled = newAcl.Enabled if acl.ID != newAcl.ID { database.DeleteRecord(database.ACLS_TABLE_NAME, acl.ID.String()) @@ -213,6 +215,15 @@ func UpdateAcl(newAcl, acl models.Acl) error { return database.Insert(acl.ID.String(), string(d), database.ACLS_TABLE_NAME) } +// UpsertAcl - upserts acl +func UpsertAcl(acl models.Acl) error { + 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()) @@ -325,7 +336,7 @@ func ListAcls(netID models.NetworkID) ([]models.Acl, error) { func convAclTagToValueMap(acltags []models.AclPolicyTag) map[string]struct{} { aclValueMap := make(map[string]struct{}) for _, aclTagI := range acltags { - aclValueMap[aclTagI.ID.String()] = struct{}{} + aclValueMap[aclTagI.Value] = struct{}{} } return aclValueMap } @@ -344,6 +355,10 @@ func IsNodeAllowedToCommunicate(node, peer models.Node) bool { for _, policy := range policies { srcMap := convAclTagToValueMap(policy.Src) dstMap := convAclTagToValueMap(policy.Dst) + fmt.Printf("\n======> SRCMAP: %+v\n", srcMap) + fmt.Printf("\n======> DSTMAP: %+v\n", dstMap) + fmt.Printf("\n======> node Tags: %+v\n", node.Tags) + fmt.Printf("\n======> peer Tags: %+v\n", peer.Tags) for tagID := range peer.Tags { if _, ok := dstMap[tagID.String()]; ok { for tagID := range node.Tags { @@ -370,3 +385,51 @@ func SortAclEntrys(acls []models.Acl) { return acls[i].Name < acls[j].Name }) } + +// UpdateDeviceTag - updates device tag on acl policies +func UpdateDeviceTag(OldID, newID models.TagID, netID models.NetworkID) { + acls := listDevicePolicies(netID) + update := false + for _, acl := range acls { + for i, srcTagI := range acl.Src { + if srcTagI.ID == models.DeviceAclID { + if OldID.String() == srcTagI.Value { + acl.Src[i].Value = newID.String() + update = true + } + } + } + for i, dstTagI := range acl.Dst { + if dstTagI.ID == models.DeviceAclID { + if OldID.String() == dstTagI.Value { + acl.Dst[i].Value = newID.String() + update = true + } + } + } + if update { + UpsertAcl(acl) + } + } +} + +func RemoveDeviceTagFromAclPolicies(tagID models.TagID, netID models.NetworkID) error { + acls := listDevicePolicies(netID) + for _, acl := range acls { + for i, srcTagI := range acl.Src { + if srcTagI.ID == models.DeviceAclID { + if tagID.String() == srcTagI.Value { + acl.Src = append(acl.Src[:i], acl.Src[i+1:]...) + } + } + } + for i, dstTagI := range acl.Dst { + if dstTagI.ID == models.DeviceAclID { + if tagID.String() == dstTagI.Value { + acl.Dst = append(acl.Dst[:i], acl.Dst[i+1:]...) + } + } + } + } + return nil +} diff --git a/logic/tags.go b/logic/tags.go index 5b89bc89..c5ef61df 100644 --- a/logic/tags.go +++ b/logic/tags.go @@ -61,6 +61,8 @@ func DeleteTag(tagID models.TagID) error { UpsertNode(&nodeI) } } + // remove tag used on acl policy + go RemoveDeviceTagFromAclPolicies(tagID, tag.Network) return database.DeleteRecord(database.TAG_TABLE_NAME, tagID.String()) }