Kaynağa Gözat

NM-82: auto create new group network policies (#3610)

* check for all network user groups on gateways selection

* check network admin policy for admins and superadmins

* auto create default group gateways policies

* publish peer update on user group updates

* update name for default group policy
Abhishek K 2 hafta önce
ebeveyn
işleme
c3498004c1
3 değiştirilmiş dosya ile 98 ekleme ve 41 silme
  1. 2 39
      pro/controllers/users.go
  2. 9 0
      pro/logic/acls.go
  3. 87 2
      pro/logic/user_mgmt.go

+ 2 - 39
pro/controllers/users.go

@@ -474,45 +474,6 @@ func createUserGroup(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	for networkID := range userGroupReq.Group.NetworkRoles {
-		network, err := logic.GetNetwork(networkID.String())
-		if err != nil {
-			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
-			return
-		}
-
-		acl := models.Acl{
-			ID:          uuid.New().String(),
-			Name:        fmt.Sprintf("%s group", userGroupReq.Group.Name),
-			MetaData:    "This Policy allows user group to communicate with all gateways",
-			Default:     false,
-			ServiceType: models.Any,
-			NetworkID:   models.NetworkID(network.NetID),
-			Proto:       models.ALL,
-			RuleType:    models.UserPolicy,
-			Src: []models.AclPolicyTag{
-				{
-					ID:    models.UserGroupAclID,
-					Value: userGroupReq.Group.ID.String(),
-				},
-			},
-			Dst: []models.AclPolicyTag{
-				{
-					ID:    models.NodeTagID,
-					Value: fmt.Sprintf("%s.%s", models.NetworkID(network.NetID), models.GwTagName),
-				}},
-			AllowedDirection: models.TrafficDirectionUni,
-			Enabled:          true,
-			CreatedBy:        "auto",
-			CreatedAt:        time.Now().UTC(),
-		}
-		err = logic.InsertAcl(acl)
-		if err != nil {
-			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
-			return
-		}
-	}
-
 	for _, userID := range userGroupReq.Members {
 		user, err := logic.GetUser(userID)
 		if err != nil {
@@ -539,6 +500,7 @@ func createUserGroup(w http.ResponseWriter, r *http.Request) {
 		},
 		Origin: models.Dashboard,
 	})
+	go mq.PublishPeerUpdate(false)
 	logic.ReturnSuccessResponseWithJson(w, r, userGroupReq.Group, "created user group")
 }
 
@@ -898,6 +860,7 @@ func deleteUserGroup(w http.ResponseWriter, r *http.Request) {
 	}()
 
 	go proLogic.UpdatesUserGwAccessOnGrpUpdates(userG.ID, userG.NetworkRoles, make(map[models.NetworkID]map[models.UserRoleID]struct{}))
+	go mq.PublishPeerUpdate(false)
 	logic.ReturnSuccessResponseWithJson(w, r, nil, "deleted user group")
 }
 

+ 9 - 0
pro/logic/acls.go

@@ -449,6 +449,15 @@ func ListUserPolicies(u models.User) []models.Acl {
 func listPoliciesOfUser(user models.User, netID models.NetworkID) []models.Acl {
 	allAcls := logic.ListAcls()
 	userAcls := []models.Acl{}
+	if _, ok := user.UserGroups[globalNetworksAdminGroupID]; ok {
+		user.UserGroups[GetDefaultNetworkAdminGroupID(netID)] = struct{}{}
+	}
+	if _, ok := user.UserGroups[globalNetworksUserGroupID]; ok {
+		user.UserGroups[GetDefaultNetworkUserGroupID(netID)] = struct{}{}
+	}
+	if user.PlatformRoleID == models.AdminRole || user.PlatformRoleID == models.SuperAdminRole {
+		user.UserGroups[GetDefaultNetworkAdminGroupID(netID)] = struct{}{}
+	}
 	for _, acl := range allAcls {
 		if acl.NetworkID == netID && acl.RuleType == models.UserPolicy {
 			srcMap := logic.ConvAclTagToValueMap(acl.Src)

+ 87 - 2
pro/logic/user_mgmt.go

@@ -597,7 +597,13 @@ func CreateUserGroup(g *models.UserGroup) error {
 	if err != nil {
 		return err
 	}
-	return database.Insert(g.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)
+	err = database.Insert(g.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)
+	if err != nil {
+		return err
+	}
+	// create default network gateway policies
+	CreateDefaultUserGroupNetworkPolicies(*g)
+	return nil
 }
 
 // GetUserGroup - fetches user group
@@ -662,11 +668,16 @@ func UpdateUserGroup(g models.UserGroup) error {
 	if err != nil {
 		return err
 	}
+
 	return database.Insert(g.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)
 }
 
 // DeleteUserGroup - deletes user group
 func DeleteUserGroup(gid models.UserGroupID) error {
+	g, err := GetUserGroup(gid)
+	if err != nil {
+		return err
+	}
 	users, err := logic.GetUsersDB()
 	if err != nil && !database.IsEmptyRecord(err) {
 		return err
@@ -675,6 +686,8 @@ func DeleteUserGroup(gid models.UserGroupID) error {
 		delete(user.UserGroups, gid)
 		logic.UpsertUser(user)
 	}
+	// create default network gateway policies
+	DeleteDefaultUserGroupNetworkPolicies(g)
 	return database.DeleteRecord(database.USER_GROUPS_TABLE_NAME, gid.String())
 }
 
@@ -745,7 +758,10 @@ func GetUserRAGNodes(user models.User) (gws map[string]models.Node) {
 			continue
 		}
 		if user.PlatformRoleID == models.AdminRole || user.PlatformRoleID == models.SuperAdminRole {
-			gws[node.ID.String()] = node
+			if ok, _ := IsUserAllowedToCommunicate(user.UserName, node); ok {
+				gws[node.ID.String()] = node
+				continue
+			}
 		} else {
 			// check if user has network role assigned
 			if roles, ok := user.NetworkRoles[models.NetworkID(node.Network)]; ok && len(roles) > 0 {
@@ -1232,6 +1248,75 @@ func UpdateUserGwAccess(currentUser, changeUser models.User) {
 
 }
 
+func CreateDefaultUserGroupNetworkPolicies(g models.UserGroup) {
+	for networkID := range g.NetworkRoles {
+		network, err := logic.GetNetwork(networkID.String())
+		if err != nil {
+			continue
+		}
+
+		acl := models.Acl{
+			ID:          uuid.New().String(),
+			Name:        fmt.Sprintf("%s group", g.Name),
+			MetaData:    "This Policy allows user group to communicate with all gateways",
+			Default:     true,
+			ServiceType: models.Any,
+			NetworkID:   models.NetworkID(network.NetID),
+			Proto:       models.ALL,
+			RuleType:    models.UserPolicy,
+			Src: []models.AclPolicyTag{
+				{
+					ID:    models.UserGroupAclID,
+					Value: g.ID.String(),
+				},
+			},
+			Dst: []models.AclPolicyTag{
+				{
+					ID:    models.NodeTagID,
+					Value: fmt.Sprintf("%s.%s", models.NetworkID(network.NetID), models.GwTagName),
+				}},
+			AllowedDirection: models.TrafficDirectionUni,
+			Enabled:          true,
+			CreatedBy:        "auto",
+			CreatedAt:        time.Now().UTC(),
+		}
+		logic.InsertAcl(acl)
+
+	}
+}
+
+func DeleteDefaultUserGroupNetworkPolicies(g models.UserGroup) {
+	for networkID := range g.NetworkRoles {
+		acls, err := logic.ListAclsByNetwork(networkID)
+		if err != nil {
+			continue
+		}
+
+		for _, acl := range acls {
+			var hasGroupSrc bool
+			newAclSrc := make([]models.AclPolicyTag, 0)
+			for _, src := range acl.Src {
+				if src.ID == models.UserGroupAclID && src.Value == g.ID.String() {
+					hasGroupSrc = true
+				} else {
+					newAclSrc = append(newAclSrc, src)
+				}
+			}
+
+			if hasGroupSrc {
+				if len(newAclSrc) == 0 {
+					// no other src exists, delete acl.
+					_ = logic.DeleteAcl(acl)
+				} else {
+					// other sources exist, update acl.
+					acl.Src = newAclSrc
+					_ = logic.UpsertAcl(acl)
+				}
+			}
+		}
+	}
+}
+
 func CreateDefaultUserPolicies(netID models.NetworkID) {
 	if netID.String() == "" {
 		return