浏览代码

Merge pull request #3171 from gravitl/NET-1719

NET-1719: Simplify User Mgmt, Use UUID for ACLs, extclient egress range rules
Abhishek K 10 月之前
父节点
当前提交
8bbc321983
共有 18 个文件被更改,包括 272 次插入291 次删除
  1. 3 11
      controllers/acls.go
  2. 0 13
      controllers/hosts.go
  3. 24 43
      logic/acls.go
  4. 95 22
      logic/extpeers.go
  5. 1 29
      logic/gateway.go
  6. 1 13
      logic/hosts.go
  7. 0 4
      logic/nodes.go
  8. 2 1
      logic/peers.go
  9. 5 0
      logic/user_mgmt.go
  10. 1 0
      main.go
  11. 9 63
      migrate/migrate.go
  12. 4 19
      models/acl.go
  13. 10 8
      models/mqtt.go
  14. 4 1
      models/user_mgmt.go
  15. 4 4
      pro/controllers/users.go
  16. 2 0
      pro/initialize.go
  17. 54 0
      pro/logic/migrate.go
  18. 53 60
      pro/logic/user_mgmt.go

+ 3 - 11
controllers/acls.go

@@ -7,6 +7,7 @@ import (
 	"net/url"
 	"time"
 
+	"github.com/google/uuid"
 	"github.com/gorilla/mux"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/logic"
@@ -44,7 +45,6 @@ func aclPolicyTypes(w http.ResponseWriter, r *http.Request) {
 		},
 		SrcGroupTypes: []models.AclGroupType{
 			models.UserAclID,
-			//models.UserRoleAclID,
 			models.UserGroupAclID,
 			models.DeviceAclID,
 		},
@@ -129,7 +129,7 @@ func createAcl(w http.ResponseWriter, r *http.Request) {
 	}
 
 	acl := req
-	acl.GetID(req.NetworkID, req.Name)
+	acl.ID = uuid.New().String()
 	acl.CreatedBy = user.UserName
 	acl.CreatedAt = time.Now().UTC()
 	acl.Default = false
@@ -188,14 +188,6 @@ func updateAcl(w http.ResponseWriter, r *http.Request) {
 	}
 	if !acl.Default && updateAcl.NewName != "" {
 		//check if policy exists with same name
-		id := models.FormatAclID(updateAcl.NetworkID, updateAcl.NewName)
-		_, err := logic.GetAcl(id)
-		if err == nil {
-			logic.ReturnErrorResponse(w, r,
-				logic.FormatError(errors.New("policy already exists with name "+updateAcl.NewName), "badrequest"))
-			return
-		}
-		updateAcl.ID = id
 		updateAcl.Acl.Name = updateAcl.NewName
 	}
 	err = logic.UpdateAcl(updateAcl.Acl, acl)
@@ -219,7 +211,7 @@ func deleteAcl(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("acl id is required"), "badrequest"))
 		return
 	}
-	acl, err := logic.GetAcl(models.AclID(aclID))
+	acl, err := logic.GetAcl(aclID)
 	if err != nil {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return

+ 0 - 13
controllers/hosts.go

@@ -253,19 +253,6 @@ func updateHost(w http.ResponseWriter, r *http.Request) {
 
 	newHost := newHostData.ConvertAPIHostToNMHost(currHost)
 
-	if newHost.Name != currHost.Name {
-		// update any rag role ids
-		for _, nodeID := range newHost.Nodes {
-			node, err := logic.GetNodeByID(nodeID)
-			if err == nil && node.IsIngressGateway {
-				role, err := logic.GetRole(models.GetRAGRoleID(node.Network, currHost.ID.String()))
-				if err == nil {
-					role.UiName = models.GetRAGRoleName(node.Network, newHost.Name)
-					logic.UpdateRole(role)
-				}
-			}
-		}
-	}
 	logic.UpdateHost(newHost, currHost) // update the in memory struct values
 	if err = logic.UpsertHost(newHost); err != nil {
 		logger.Log(0, r.Header.Get("user"), "failed to update a host:", err.Error())

+ 24 - 43
logic/acls.go

@@ -16,10 +16,11 @@ func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
 	if netID.String() == "" {
 		return
 	}
-	if !IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, "all-nodes"))) {
+	if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-nodes")) {
 		defaultDeviceAcl := models.Acl{
-			ID:        models.AclID(fmt.Sprintf("%s.%s", netID, "all-nodes")),
-			Name:      "all-nodes",
+			ID:        fmt.Sprintf("%s.%s", netID, "all-nodes"),
+			Name:      "All Nodes",
+			MetaData:  "This Policy allows all nodes in the network to communicate with each other",
 			Default:   true,
 			NetworkID: netID,
 			RuleType:  models.DevicePolicy,
@@ -40,11 +41,12 @@ func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
 		}
 		InsertAcl(defaultDeviceAcl)
 	}
-	if !IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, "all-users"))) {
+	if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-users")) {
 		defaultUserAcl := models.Acl{
-			ID:        models.AclID(fmt.Sprintf("%s.%s", netID, "all-users")),
+			ID:        fmt.Sprintf("%s.%s", netID, "all-users"),
 			Default:   true,
-			Name:      "all-users",
+			Name:      "All Users",
+			MetaData:  "This policy gives access to everything in the network for an user",
 			NetworkID: netID,
 			RuleType:  models.UserPolicy,
 			Src: []models.AclPolicyTag{
@@ -56,10 +58,6 @@ func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
 					ID:    models.UserGroupAclID,
 					Value: "*",
 				},
-				// {
-				// 	ID:    models.UserRoleAclID,
-				// 	Value: "*",
-				// },
 			},
 			Dst: []models.AclPolicyTag{{
 				ID:    models.DeviceAclID,
@@ -73,11 +71,11 @@ func CreateDefaultAclNetworkPolicies(netID models.NetworkID) {
 		InsertAcl(defaultUserAcl)
 	}
 
-	if !IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, "all-remote-access-gws"))) {
+	if !IsAclExists(fmt.Sprintf("%s.%s", netID, "all-remote-access-gws")) {
 		defaultUserAcl := models.Acl{
-			ID:        models.AclID(fmt.Sprintf("%s.%s", netID, "all-remote-access-gws")),
+			ID:        fmt.Sprintf("%s.%s", netID, "all-remote-access-gws"),
 			Default:   true,
-			Name:      "all-remote-access-gws",
+			Name:      "All Remote Access Gateways",
 			NetworkID: netID,
 			RuleType:  models.DevicePolicy,
 			Src: []models.AclPolicyTag{
@@ -119,15 +117,10 @@ func ValidateCreateAclReq(req models.Acl) error {
 	if err != nil {
 		return errors.New("failed to get network details for " + req.NetworkID.String())
 	}
-	err = CheckIDSyntax(req.Name)
-	if err != nil {
-		return err
-	}
-	req.GetID(req.NetworkID, req.Name)
-	_, err = GetAcl(req.ID)
-	if err == nil {
-		return errors.New("acl exists already with name " + req.Name)
-	}
+	// err = CheckIDSyntax(req.Name)
+	// if err != nil {
+	// 	return err
+	// }
 	return nil
 }
 
@@ -137,13 +130,13 @@ func InsertAcl(a models.Acl) error {
 	if err != nil {
 		return err
 	}
-	return database.Insert(a.ID.String(), string(d), database.ACLS_TABLE_NAME)
+	return database.Insert(a.ID, string(d), database.ACLS_TABLE_NAME)
 }
 
 // GetAcl - gets acl info by id
-func GetAcl(aID models.AclID) (models.Acl, error) {
+func GetAcl(aID string) (models.Acl, error) {
 	a := models.Acl{}
-	d, err := database.FetchRecord(database.ACLS_TABLE_NAME, aID.String())
+	d, err := database.FetchRecord(database.ACLS_TABLE_NAME, aID)
 	if err != nil {
 		return a, err
 	}
@@ -155,7 +148,7 @@ func GetAcl(aID models.AclID) (models.Acl, error) {
 }
 
 // IsAclExists - checks if acl exists
-func IsAclExists(aclID models.AclID) bool {
+func IsAclExists(aclID string) bool {
 	_, err := GetAcl(aclID)
 	return err == nil
 }
@@ -175,9 +168,7 @@ func IsAclPolicyValid(acl models.Acl) bool {
 			if srcI.Value == "*" {
 				continue
 			}
-			if srcI.ID != models.UserAclID {
-				// &&	srcI.ID != models.UserGroupAclID && srcI.ID != models.UserRoleAclID
-
+			if srcI.ID != models.UserAclID && srcI.ID != models.UserGroupAclID {
 				return false
 			}
 			// check if user group is valid
@@ -186,12 +177,6 @@ func IsAclPolicyValid(acl models.Acl) bool {
 				if err != nil {
 					return false
 				}
-				// } else if srcI.ID == models.UserRoleAclID {
-
-				// 	_, err := GetRole(models.UserRoleID(srcI.Value))
-				// 	if err != nil {
-				// 		return false
-				// 	}
 
 			} else if srcI.ID == models.UserGroupAclID {
 				err := IsGroupValid(models.UserGroupID(srcI.Value))
@@ -264,15 +249,11 @@ func UpdateAcl(newAcl, acl models.Acl) error {
 		acl.Dst = newAcl.Dst
 	}
 	acl.Enabled = newAcl.Enabled
-	if acl.ID != newAcl.ID {
-		database.DeleteRecord(database.ACLS_TABLE_NAME, acl.ID.String())
-		acl.ID = newAcl.ID
-	}
 	d, err := json.Marshal(acl)
 	if err != nil {
 		return err
 	}
-	return database.Insert(acl.ID.String(), string(d), database.ACLS_TABLE_NAME)
+	return database.Insert(acl.ID, string(d), database.ACLS_TABLE_NAME)
 }
 
 // UpsertAcl - upserts acl
@@ -281,12 +262,12 @@ func UpsertAcl(acl models.Acl) error {
 	if err != nil {
 		return err
 	}
-	return database.Insert(acl.ID.String(), string(d), database.ACLS_TABLE_NAME)
+	return database.Insert(acl.ID, 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())
+	return database.DeleteRecord(database.ACLS_TABLE_NAME, a.ID)
 }
 
 // GetDefaultPolicy - fetches default policy in the network by ruleType
@@ -295,7 +276,7 @@ func GetDefaultPolicy(netID models.NetworkID, ruleType models.AclPolicyType) (mo
 	if ruleType == models.DevicePolicy {
 		aclID = "all-nodes"
 	}
-	acl, err := GetAcl(models.AclID(fmt.Sprintf("%s.%s", netID, aclID)))
+	acl, err := GetAcl(fmt.Sprintf("%s.%s", netID, aclID))
 	if err != nil {
 		return models.Acl{}, errors.New("default rule not found")
 	}

+ 95 - 22
logic/extpeers.go

@@ -443,39 +443,62 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
 					if userNodeI.StaticNode.Address != "" {
 						if !defaultUserPolicy.Enabled {
 							rules = append(rules, models.FwRule{
-								SrcIp: userNodeI.StaticNode.AddressIPNet4().IP,
-								DstIP: peer.StaticNode.AddressIPNet4().IP,
+								SrcIP: userNodeI.StaticNode.AddressIPNet4(),
+								DstIP: peer.StaticNode.AddressIPNet4(),
 								Allow: true,
 							})
 						}
 						rules = append(rules, models.FwRule{
-							SrcIp: peer.StaticNode.AddressIPNet4().IP,
-							DstIP: userNodeI.StaticNode.AddressIPNet4().IP,
+							SrcIP: peer.StaticNode.AddressIPNet4(),
+							DstIP: userNodeI.StaticNode.AddressIPNet4(),
 							Allow: true,
 						})
 					}
 					if userNodeI.StaticNode.Address6 != "" {
 						if !defaultUserPolicy.Enabled {
 							rules = append(rules, models.FwRule{
-								SrcIp: userNodeI.StaticNode.AddressIPNet6().IP,
-								DstIP: peer.StaticNode.AddressIPNet6().IP,
+								SrcIP: userNodeI.StaticNode.AddressIPNet6(),
+								DstIP: peer.StaticNode.AddressIPNet6(),
 								Allow: true,
 							})
 						}
 
 						rules = append(rules, models.FwRule{
-							SrcIp: peer.StaticNode.AddressIPNet6().IP,
-							DstIP: userNodeI.StaticNode.AddressIPNet6().IP,
+							SrcIP: peer.StaticNode.AddressIPNet6(),
+							DstIP: userNodeI.StaticNode.AddressIPNet6(),
 							Allow: true,
 						})
 					}
+					if len(peer.StaticNode.ExtraAllowedIPs) > 0 {
+						for _, additionalAllowedIPNet := range peer.StaticNode.ExtraAllowedIPs {
+							_, ipNet, err := net.ParseCIDR(additionalAllowedIPNet)
+							if err != nil {
+								continue
+							}
+							if ipNet.IP.To4() != nil {
+								rules = append(rules, models.FwRule{
+									SrcIP: userNodeI.StaticNode.AddressIPNet4(),
+									DstIP: *ipNet,
+									Allow: true,
+								})
+							} else {
+								rules = append(rules, models.FwRule{
+									SrcIP: userNodeI.StaticNode.AddressIPNet6(),
+									DstIP: *ipNet,
+									Allow: true,
+								})
+							}
+
+						}
+
+					}
 				} else {
 
 					if userNodeI.StaticNode.Address != "" {
 						if !defaultUserPolicy.Enabled {
 							rules = append(rules, models.FwRule{
-								SrcIp: userNodeI.StaticNode.AddressIPNet4().IP,
-								DstIP: peer.Address.IP,
+								SrcIP: userNodeI.StaticNode.AddressIPNet4(),
+								DstIP: peer.Address,
 								Allow: true,
 							})
 						}
@@ -483,8 +506,8 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
 
 					if userNodeI.StaticNode.Address6 != "" {
 						rules = append(rules, models.FwRule{
-							SrcIp: userNodeI.StaticNode.AddressIPNet6().IP,
-							DstIP: peer.Address6.IP,
+							SrcIP: userNodeI.StaticNode.AddressIPNet6(),
+							DstIP: peer.Address6,
 							Allow: true,
 						})
 					}
@@ -509,30 +532,53 @@ func GetFwRulesOnIngressGateway(node models.Node) (rules []models.FwRule) {
 				if peer.IsStatic {
 					if nodeI.StaticNode.Address != "" {
 						rules = append(rules, models.FwRule{
-							SrcIp: nodeI.StaticNode.AddressIPNet4().IP,
-							DstIP: peer.StaticNode.AddressIPNet4().IP,
+							SrcIP: nodeI.StaticNode.AddressIPNet4(),
+							DstIP: peer.StaticNode.AddressIPNet4(),
 							Allow: true,
 						})
 					}
 					if nodeI.StaticNode.Address6 != "" {
 						rules = append(rules, models.FwRule{
-							SrcIp: nodeI.StaticNode.AddressIPNet6().IP,
-							DstIP: peer.StaticNode.AddressIPNet6().IP,
+							SrcIP: nodeI.StaticNode.AddressIPNet6(),
+							DstIP: peer.StaticNode.AddressIPNet6(),
 							Allow: true,
 						})
 					}
+					if len(peer.StaticNode.ExtraAllowedIPs) > 0 {
+						for _, additionalAllowedIPNet := range peer.StaticNode.ExtraAllowedIPs {
+							_, ipNet, err := net.ParseCIDR(additionalAllowedIPNet)
+							if err != nil {
+								continue
+							}
+							if ipNet.IP.To4() != nil {
+								rules = append(rules, models.FwRule{
+									SrcIP: nodeI.StaticNode.AddressIPNet4(),
+									DstIP: *ipNet,
+									Allow: true,
+								})
+							} else {
+								rules = append(rules, models.FwRule{
+									SrcIP: nodeI.StaticNode.AddressIPNet6(),
+									DstIP: *ipNet,
+									Allow: true,
+								})
+							}
+
+						}
+
+					}
 				} else {
 					if nodeI.StaticNode.Address != "" {
 						rules = append(rules, models.FwRule{
-							SrcIp: nodeI.StaticNode.AddressIPNet4().IP,
-							DstIP: peer.Address.IP,
+							SrcIP: nodeI.StaticNode.AddressIPNet4(),
+							DstIP: peer.Address,
 							Allow: true,
 						})
 					}
 					if nodeI.StaticNode.Address6 != "" {
 						rules = append(rules, models.FwRule{
-							SrcIp: nodeI.StaticNode.AddressIPNet6().IP,
-							DstIP: peer.Address6.IP,
+							SrcIP: nodeI.StaticNode.AddressIPNet6(),
+							DstIP: peer.Address6,
 							Allow: true,
 						})
 					}
@@ -642,8 +688,35 @@ func getExtPeerEgressRoute(node models.Node, extPeer models.ExtClient) (egressRo
 	return
 }
 
-func getExtpeersExtraRoutes(node models.Node, network string) (egressRoutes []models.EgressNetworkRoutes) {
-	extPeers, err := GetNetworkExtClients(network)
+func getExtpeerEgressRanges(node models.Node) (ranges, ranges6 []net.IPNet) {
+	extPeers, err := GetNetworkExtClients(node.Network)
+	if err != nil {
+		return
+	}
+	for _, extPeer := range extPeers {
+		if len(extPeer.ExtraAllowedIPs) == 0 {
+			continue
+		}
+		if !IsNodeAllowedToCommunicate(extPeer.ConvertToStaticNode(), node) {
+			continue
+		}
+		for _, allowedRange := range extPeer.ExtraAllowedIPs {
+			_, ipnet, err := net.ParseCIDR(allowedRange)
+			if err == nil {
+				if ipnet.IP.To4() != nil {
+					ranges = append(ranges, *ipnet)
+				} else {
+					ranges6 = append(ranges6, *ipnet)
+				}
+
+			}
+		}
+	}
+	return
+}
+
+func getExtpeersExtraRoutes(node models.Node) (egressRoutes []models.EgressNetworkRoutes) {
+	extPeers, err := GetNetworkExtClients(node.Network)
 	if err != nil {
 		return
 	}

+ 1 - 29
logic/gateway.go

@@ -188,30 +188,6 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq
 	if err != nil {
 		return models.Node{}, err
 	}
-	// create network role for this gateway
-	CreateRole(models.UserRolePermissionTemplate{
-		ID:        models.GetRAGRoleID(node.Network, host.ID.String()),
-		UiName:    models.GetRAGRoleName(node.Network, host.Name),
-		NetworkID: models.NetworkID(node.Network),
-		Default:   true,
-		NetworkLevelAccess: map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope{
-			models.RemoteAccessGwRsrc: {
-				models.RsrcID(node.ID.String()): models.RsrcPermissionScope{
-					Read:      true,
-					VPNaccess: true,
-				},
-			},
-			models.ExtClientsRsrc: {
-				models.AllExtClientsRsrcID: models.RsrcPermissionScope{
-					Read:     true,
-					Create:   true,
-					Update:   true,
-					Delete:   true,
-					SelfOnly: true,
-				},
-			},
-		},
-	})
 	err = SetNetworkNodesLastModified(netid)
 	return node, err
 }
@@ -266,11 +242,7 @@ func DeleteIngressGateway(nodeid string) (models.Node, []models.ExtClient, error
 	if err != nil {
 		return models.Node{}, removedClients, err
 	}
-	host, err := GetHost(node.HostID.String())
-	if err != nil {
-		return models.Node{}, removedClients, err
-	}
-	go DeleteRole(models.GetRAGRoleID(node.Network, host.ID.String()), true)
+
 	err = SetNetworkNodesLastModified(node.Network)
 	return node, removedClients, err
 }

+ 1 - 13
logic/hosts.go

@@ -287,19 +287,7 @@ func UpdateHostFromClient(newHost, currHost *models.Host) (sendPeerUpdate bool)
 	currHost.IsStaticPort = newHost.IsStaticPort
 	currHost.IsStatic = newHost.IsStatic
 	currHost.MTU = newHost.MTU
-	if newHost.Name != currHost.Name {
-		// update any rag role ids
-		for _, nodeID := range newHost.Nodes {
-			node, err := GetNodeByID(nodeID)
-			if err == nil && node.IsIngressGateway {
-				role, err := GetRole(models.GetRAGRoleID(node.Network, currHost.ID.String()))
-				if err == nil {
-					role.UiName = models.GetRAGRoleName(node.Network, newHost.Name)
-					UpdateRole(role)
-				}
-			}
-		}
-	}
+
 	currHost.Name = newHost.Name
 	if len(newHost.NatType) > 0 && newHost.NatType != currHost.NatType {
 		currHost.NatType = newHost.NatType

+ 0 - 4
logic/nodes.go

@@ -196,10 +196,6 @@ func DeleteNode(node *models.Node, purge bool) error {
 		if err := DeleteGatewayExtClients(node.ID.String(), node.Network); err != nil {
 			slog.Error("failed to delete ext clients", "nodeid", node.ID.String(), "error", err.Error())
 		}
-		host, err := GetHost(node.HostID.String())
-		if err == nil {
-			go DeleteRole(models.GetRAGRoleID(node.Network, host.ID.String()), true)
-		}
 	}
 	if node.IsRelayed {
 		// cleanup node from relayednodes on relay node

+ 2 - 1
logic/peers.go

@@ -183,7 +183,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 				})
 			}
 			if peer.IsIngressGateway {
-				hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(node, peer.Network)...)
+				hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(node)...)
 			}
 			_, isFailOverPeer := node.FailOverPeers[peer.ID.String()]
 			if servercfg.IsPro {
@@ -303,6 +303,7 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 						StaticNodeIps: GetStaticNodeIps(node),
 						Rules:         GetFwRulesOnIngressGateway(node),
 					}
+					ingFwUpdate.EgressRanges, ingFwUpdate.EgressRanges6 = getExtpeerEgressRanges(node)
 					hostPeerUpdate.FwUpdate.IngressInfo[node.ID.String()] = ingFwUpdate
 				}
 				hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, egressRoutes...)

+ 5 - 0
logic/user_mgmt.go

@@ -46,11 +46,16 @@ var IsNetworkRolesValid = func(networkRoles map[models.NetworkID]map[models.User
 	return nil
 }
 
+var MigrateUserRoleAndGroups = func(u models.User) {
+
+}
+
 var UpdateUserGwAccess = func(currentUser, changeUser models.User) {}
 
 var UpdateRole = func(r models.UserRolePermissionTemplate) error { return nil }
 
 var InitialiseRoles = userRolesInit
+var IntialiseGroups = func() {}
 var DeleteNetworkRoles = func(netID string) {}
 var CreateDefaultNetworkRolesAndGroups = func(netID models.NetworkID) {}
 var CreateDefaultUserPolicies = func(netID models.NetworkID) {}

+ 1 - 0
main.go

@@ -103,6 +103,7 @@ func initialize() { // Client Mode Prereq Check
 
 	logic.SetJWTSecret()
 	logic.InitialiseRoles()
+	logic.IntialiseGroups()
 	err = serverctl.SetDefaults()
 	if err != nil {
 		logger.FatalLog("error setting defaults: ", err.Error())

+ 9 - 63
migrate/migrate.go

@@ -178,7 +178,10 @@ func updateNodes() {
 				node.Tags[tagID] = struct{}{}
 				logic.UpsertNode(&node)
 			}
-
+			host, err := logic.GetHost(node.HostID.String())
+			if err == nil {
+				go logic.DeleteRole(models.GetRAGRoleID(node.Network, host.ID.String()), true)
+			}
 		}
 		if node.IsEgressGateway {
 			egressRanges, update := removeInterGw(node.EgressGatewayRanges)
@@ -356,42 +359,8 @@ func syncUsers() {
 	// create default network user roles for existing networks
 	if servercfg.IsPro {
 		networks, _ := logic.GetNetworks()
-		nodes, err := logic.GetAllNodes()
-		if err == nil {
-			for _, netI := range networks {
-				logic.CreateDefaultNetworkRolesAndGroups(models.NetworkID(netI.NetID))
-				networkNodes := logic.GetNetworkNodesMemory(nodes, netI.NetID)
-				for _, networkNodeI := range networkNodes {
-					if networkNodeI.IsIngressGateway {
-						h, err := logic.GetHost(networkNodeI.HostID.String())
-						if err == nil {
-							logic.CreateRole(models.UserRolePermissionTemplate{
-								ID:        models.GetRAGRoleID(networkNodeI.Network, h.ID.String()),
-								UiName:    models.GetRAGRoleName(networkNodeI.Network, h.Name),
-								NetworkID: models.NetworkID(netI.NetID),
-								NetworkLevelAccess: map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope{
-									models.RemoteAccessGwRsrc: {
-										models.RsrcID(networkNodeI.ID.String()): models.RsrcPermissionScope{
-											Read:      true,
-											VPNaccess: true,
-										},
-									},
-									models.ExtClientsRsrc: {
-										models.AllExtClientsRsrcID: models.RsrcPermissionScope{
-											Read:     true,
-											Create:   true,
-											Update:   true,
-											Delete:   true,
-											SelfOnly: true,
-										},
-									},
-								},
-							})
-						}
-
-					}
-				}
-			}
+		for _, netI := range networks {
+			logic.CreateDefaultNetworkRolesAndGroups(models.NetworkID(netI.NetID))
 		}
 	}
 
@@ -429,34 +398,11 @@ func syncUsers() {
 				user.PlatformRoleID = models.ServiceUser
 			}
 			logic.UpsertUser(user)
-			if len(user.RemoteGwIDs) > 0 {
-				// define user roles for network
-				// assign relevant network role to user
-				for remoteGwID := range user.RemoteGwIDs {
-					gwNode, err := logic.GetNodeByID(remoteGwID)
-					if err != nil {
-						continue
-					}
-					h, err := logic.GetHost(gwNode.HostID.String())
-					if err != nil {
-						continue
-					}
-					r, err := logic.GetRole(models.GetRAGRoleID(gwNode.Network, h.ID.String()))
-					if err != nil {
-						continue
-					}
-					if netRoles, ok := user.NetworkRoles[models.NetworkID(gwNode.Network)]; ok {
-						netRoles[r.ID] = struct{}{}
-					} else {
-						user.NetworkRoles[models.NetworkID(gwNode.Network)] = map[models.UserRoleID]struct{}{
-							r.ID: {},
-						}
-					}
-				}
-				logic.UpsertUser(user)
-			}
+			logic.MigrateUserRoleAndGroups(user)
+
 		}
 	}
+
 }
 
 func createDefaultTagsAndPolicies() {

+ 4 - 19
models/acl.go

@@ -1,24 +1,9 @@
 package models
 
 import (
-	"fmt"
 	"time"
 )
 
-type AclID string
-
-func (aID AclID) String() string {
-	return string(aID)
-}
-
-func (a *Acl) GetID(netID NetworkID, name string) {
-	a.ID = AclID(fmt.Sprintf("%s.%s", netID.String(), name))
-}
-
-func FormatAclID(netID NetworkID, name string) AclID {
-	return AclID(fmt.Sprintf("%s.%s", netID.String(), name))
-}
-
 // AllowedTrafficDirection - allowed direction of traffic
 type AllowedTrafficDirection int
 
@@ -44,9 +29,8 @@ type AclPolicyTag struct {
 type AclGroupType string
 
 const (
-	UserAclID      AclGroupType = "user"
-	UserGroupAclID AclGroupType = "user-group"
-	//UserRoleAclID            AclGroupType = "user-role"
+	UserAclID                AclGroupType = "user"
+	UserGroupAclID           AclGroupType = "user-group"
 	DeviceAclID              AclGroupType = "tag"
 	NetmakerIPAclID          AclGroupType = "ip"
 	NetmakerSubNetRangeAClID AclGroupType = "ipset"
@@ -67,8 +51,9 @@ type AclPolicy struct {
 }
 
 type Acl struct {
-	ID               AclID                   `json:"id"`
+	ID               string                  `json:"id"`
 	Default          bool                    `json:"default"`
+	MetaData         string                  `json:"meta_data"`
 	Name             string                  `json:"name"`
 	NetworkID        NetworkID               `json:"network_id"`
 	RuleType         AclPolicyType           `json:"policy_type"`

+ 10 - 8
models/mqtt.go

@@ -27,19 +27,21 @@ type HostPeerUpdate struct {
 }
 
 type FwRule struct {
-	SrcIp net.IP
-	DstIP net.IP
+	SrcIP net.IPNet
+	DstIP net.IPNet
 	Allow bool
 }
 
 // IngressInfo - struct for ingress info
 type IngressInfo struct {
-	IngressID     string    `json:"ingress_id"`
-	Network       net.IPNet `json:"network"`
-	Network6      net.IPNet `json:"network6"`
-	StaticNodeIps []net.IP  `json:"static_node_ips"`
-	Rules         []FwRule  `json:"rules"`
-	AllowAll      bool      `json:"allow_all"`
+	IngressID     string      `json:"ingress_id"`
+	Network       net.IPNet   `json:"network"`
+	Network6      net.IPNet   `json:"network6"`
+	StaticNodeIps []net.IP    `json:"static_node_ips"`
+	Rules         []FwRule    `json:"rules"`
+	AllowAll      bool        `json:"allow_all"`
+	EgressRanges  []net.IPNet `json:"egress_ranges"`
+	EgressRanges6 []net.IPNet `json:"egress_ranges6"`
 }
 
 // EgressInfo - struct for egress info

+ 4 - 1
models/user_mgmt.go

@@ -116,8 +116,9 @@ type RsrcPermissionScope struct {
 
 type UserRolePermissionTemplate struct {
 	ID                  UserRoleID                                  `json:"id"`
-	UiName              string                                      `json:"ui_name"`
+	Name                string                                      `json:"name"`
 	Default             bool                                        `json:"default"`
+	MetaData            string                                      `json:"meta_data"`
 	DenyDashboardAccess bool                                        `json:"deny_dashboard_access"`
 	FullAccess          bool                                        `json:"full_access"`
 	NetworkID           NetworkID                                   `json:"network_id"`
@@ -132,6 +133,8 @@ type CreateGroupReq struct {
 
 type UserGroup struct {
 	ID           UserGroupID                           `json:"id"`
+	Default      bool                                  `json:"default"`
+	Name         string                                `json:"name"`
 	NetworkRoles map[NetworkID]map[UserRoleID]struct{} `json:"network_roles"`
 	MetaData     string                                `json:"meta_data"`
 }

+ 4 - 4
pro/controllers/users.go

@@ -834,7 +834,7 @@ func getUserRemoteAccessNetworks(w http.ResponseWriter, r *http.Request) {
 	userGws := make(map[string][]models.UserRemoteGws)
 	networks := []models.Network{}
 	networkMap := make(map[string]struct{})
-	userGwNodes := proLogic.GetUserRAGNodes(*user)
+	userGwNodes := proLogic.GetUserRAGNodesV1(*user)
 	for _, node := range userGwNodes {
 		network, err := logic.GetNetwork(node.Network)
 		if err != nil {
@@ -876,7 +876,7 @@ func getUserRemoteAccessNetworkGateways(w http.ResponseWriter, r *http.Request)
 	}
 	userGws := []models.UserRAGs{}
 
-	userGwNodes := proLogic.GetUserRAGNodes(*user)
+	userGwNodes := proLogic.GetUserRAGNodesV1(*user)
 	for _, node := range userGwNodes {
 		if node.Network != network {
 			continue
@@ -931,7 +931,7 @@ func getRemoteAccessGatewayConf(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	userGwNodes := proLogic.GetUserRAGNodes(*user)
+	userGwNodes := proLogic.GetUserRAGNodesV1(*user)
 	if _, ok := userGwNodes[remoteGwID]; !ok {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("access denied"), "forbidden"))
 		return
@@ -1075,7 +1075,7 @@ func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 		return
 	}
-	userGwNodes := proLogic.GetUserRAGNodes(*user)
+	userGwNodes := proLogic.GetUserRAGNodesV1(*user)
 	for _, extClient := range allextClients {
 		node, ok := userGwNodes[extClient.IngressGatewayID]
 		if !ok {

+ 2 - 0
pro/initialize.go

@@ -136,6 +136,8 @@ func InitPro() {
 	logic.InitialiseRoles = proLogic.UserRolesInit
 	logic.UpdateUserGwAccess = proLogic.UpdateUserGwAccess
 	logic.CreateDefaultUserPolicies = proLogic.CreateDefaultUserPolicies
+	logic.MigrateUserRoleAndGroups = proLogic.MigrateUserRoleAndGroups
+	logic.IntialiseGroups = proLogic.UserGroupsInit
 }
 
 func retrieveProLogo() string {

+ 54 - 0
pro/logic/migrate.go

@@ -0,0 +1,54 @@
+package logic
+
+import (
+	"fmt"
+
+	"github.com/gravitl/netmaker/logic"
+	"github.com/gravitl/netmaker/models"
+)
+
+func MigrateUserRoleAndGroups(user models.User) {
+	var err error
+	if len(user.RemoteGwIDs) > 0 {
+		// define user roles for network
+		// assign relevant network role to user
+		for remoteGwID := range user.RemoteGwIDs {
+			gwNode, err := logic.GetNodeByID(remoteGwID)
+			if err != nil {
+				continue
+			}
+			var g models.UserGroup
+			if user.PlatformRoleID == models.ServiceUser {
+				g, err = GetUserGroup(models.UserGroupID(fmt.Sprintf("%s-%s-grp", gwNode.Network, models.NetworkUser)))
+			} else {
+				g, err = GetUserGroup(models.UserGroupID(fmt.Sprintf("%s-%s-grp",
+					gwNode.Network, models.NetworkAdmin)))
+			}
+			if err != nil {
+				continue
+			}
+			user.UserGroups[g.ID] = struct{}{}
+
+		}
+	}
+	if len(user.NetworkRoles) > 0 {
+		for netID := range user.NetworkRoles {
+			var g models.UserGroup
+			if user.PlatformRoleID == models.ServiceUser {
+				g, err = GetUserGroup(models.UserGroupID(fmt.Sprintf("%s-%s-grp", netID, models.NetworkUser)))
+			} else {
+				g, err = GetUserGroup(models.UserGroupID(fmt.Sprintf("%s-%s-grp",
+					netID, models.NetworkAdmin)))
+			}
+			if err != nil {
+				continue
+			}
+			user.UserGroups[g.ID] = struct{}{}
+			if err != nil {
+				continue
+			}
+		}
+
+	}
+	logic.UpsertUser(user)
+}

+ 53 - 60
pro/logic/user_mgmt.go

@@ -30,6 +30,8 @@ var PlatformUserUserPermissionTemplate = models.UserRolePermissionTemplate{
 
 var NetworkAdminAllPermissionTemplate = models.UserRolePermissionTemplate{
 	ID:         models.UserRoleID(fmt.Sprintf("global-%s", models.NetworkAdmin)),
+	Name:       "Network Admins",
+	MetaData:   "Users with this role can manage all your networks configuration including adding and removing devices.",
 	Default:    true,
 	FullAccess: true,
 	NetworkID:  models.AllNetworks,
@@ -37,6 +39,8 @@ var NetworkAdminAllPermissionTemplate = models.UserRolePermissionTemplate{
 
 var NetworkUserAllPermissionTemplate = models.UserRolePermissionTemplate{
 	ID:         models.UserRoleID(fmt.Sprintf("global-%s", models.NetworkUser)),
+	Name:       "Network Users",
+	MetaData:   "Users with this role Cannot access the admin console, but can connect to nodes in your networks via RAC.",
 	Default:    true,
 	FullAccess: false,
 	NetworkID:  models.AllNetworks,
@@ -75,12 +79,44 @@ func UserRolesInit() {
 
 }
 
+func UserGroupsInit() {
+	// create default network groups
+	var NetworkGlobalAdminGroup = models.UserGroup{
+		ID:       models.UserGroupID(fmt.Sprintf("global-%s-grp", models.NetworkAdmin)),
+		Default:  true,
+		Name:     "Network Admin Group",
+		MetaData: "Users in this group can manage all your networks configuration including adding and removing devices.",
+		NetworkRoles: map[models.NetworkID]map[models.UserRoleID]struct{}{
+			models.NetworkID("*"): {
+				models.UserRoleID(fmt.Sprintf("global-%s", models.NetworkAdmin)): {},
+			},
+		},
+	}
+	var NetworkGlobalUserGroup = models.UserGroup{
+		ID:      models.UserGroupID(fmt.Sprintf("global-%s-grp", models.NetworkUser)),
+		Name:    "Network User Group",
+		Default: true,
+		NetworkRoles: map[models.NetworkID]map[models.UserRoleID]struct{}{
+			models.NetworkID("*"): {
+				models.UserRoleID(fmt.Sprintf("global-%s", models.NetworkUser)): {},
+			},
+		},
+		MetaData: "Users in this group cannot access the admin console, but can connect to nodes in your networks via RAC.",
+	}
+	d, _ := json.Marshal(NetworkGlobalAdminGroup)
+	database.Insert(NetworkGlobalAdminGroup.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)
+	d, _ = json.Marshal(NetworkGlobalUserGroup)
+	database.Insert(NetworkGlobalUserGroup.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)
+}
+
 func CreateDefaultNetworkRolesAndGroups(netID models.NetworkID) {
 	if netID.String() == "" {
 		return
 	}
 	var NetworkAdminPermissionTemplate = models.UserRolePermissionTemplate{
 		ID:                 models.UserRoleID(fmt.Sprintf("%s-%s", netID, models.NetworkAdmin)),
+		Name:               fmt.Sprintf("%s Admin", netID),
+		MetaData:           fmt.Sprintf("Users with this role can manage your network `%s` configuration including adding and removing devices.", netID),
 		Default:            true,
 		NetworkID:          netID,
 		FullAccess:         true,
@@ -89,6 +125,8 @@ func CreateDefaultNetworkRolesAndGroups(netID models.NetworkID) {
 
 	var NetworkUserPermissionTemplate = models.UserRolePermissionTemplate{
 		ID:                  models.UserRoleID(fmt.Sprintf("%s-%s", netID, models.NetworkUser)),
+		Name:                fmt.Sprintf("%s User", netID),
+		MetaData:            fmt.Sprintf("Users Cannot access the admin console, but can connect to nodes in your network `%s` via RAC.", netID),
 		Default:             true,
 		FullAccess:          false,
 		NetworkID:           netID,
@@ -118,22 +156,24 @@ func CreateDefaultNetworkRolesAndGroups(netID models.NetworkID) {
 
 	// create default network groups
 	var NetworkAdminGroup = models.UserGroup{
-		ID: models.UserGroupID(fmt.Sprintf("%s-%s-grp", netID, models.NetworkAdmin)),
+		ID:   models.UserGroupID(fmt.Sprintf("%s-%s-grp", netID, models.NetworkAdmin)),
+		Name: fmt.Sprintf("%s Admin Group", netID),
 		NetworkRoles: map[models.NetworkID]map[models.UserRoleID]struct{}{
 			netID: {
 				models.UserRoleID(fmt.Sprintf("%s-%s", netID, models.NetworkAdmin)): {},
 			},
 		},
-		MetaData: "The network group was automatically created by Netmaker.",
+		MetaData: fmt.Sprintf("User in this group can manage your network `%s` configuration including adding and removing devices.", netID),
 	}
 	var NetworkUserGroup = models.UserGroup{
-		ID: models.UserGroupID(fmt.Sprintf("%s-%s-grp", netID, models.NetworkUser)),
+		ID:   models.UserGroupID(fmt.Sprintf("%s-%s-grp", netID, models.NetworkUser)),
+		Name: fmt.Sprintf("%s User Group", netID),
 		NetworkRoles: map[models.NetworkID]map[models.UserRoleID]struct{}{
 			netID: {
 				models.UserRoleID(fmt.Sprintf("%s-%s", netID, models.NetworkUser)): {},
 			},
 		},
-		MetaData: "The network group was automatically created by Netmaker.",
+		MetaData: fmt.Sprintf("Users in this group cannot access the admin console, but can connect to nodes in your network `%s` via RAC.", netID),
 	}
 	d, _ = json.Marshal(NetworkAdminGroup)
 	database.Insert(NetworkAdminGroup.ID.String(), string(d), database.USER_GROUPS_TABLE_NAME)
@@ -1100,60 +1140,12 @@ func CreateDefaultUserPolicies(netID models.NetworkID) {
 	if netID.String() == "" {
 		return
 	}
-	// if !logic.IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, models.NetworkAdmin))) {
-	// 	defaultUserAcl := models.Acl{
-	// 		ID:        models.AclID(fmt.Sprintf("%s.%s", netID, models.NetworkAdmin)),
-	// 		Name:      models.NetworkAdmin.String(),
-	// 		Default:   true,
-	// 		NetworkID: netID,
-	// 		RuleType:  models.UserPolicy,
-	// 		Src: []models.AclPolicyTag{
-	// 			{
-	// 				ID:    models.UserRoleAclID,
-	// 				Value: fmt.Sprintf("%s-%s", netID, models.NetworkAdmin),
-	// 			}},
-	// 		Dst: []models.AclPolicyTag{
-	// 			{
-	// 				ID:    models.DeviceAclID,
-	// 				Value: fmt.Sprintf("%s.%s", netID, models.RemoteAccessTagName),
-	// 			},
-	// 		},
-	// 		AllowedDirection: models.TrafficDirectionUni,
-	// 		Enabled:          true,
-	// 		CreatedBy:        "auto",
-	// 		CreatedAt:        time.Now().UTC(),
-	// 	}
-	// 	logic.InsertAcl(defaultUserAcl)
-	// }
-	// if !logic.IsAclExists(models.AclID(fmt.Sprintf("%s.%s", netID, models.NetworkUser))) {
-	// 	defaultUserAcl := models.Acl{
-	// 		ID:        models.AclID(fmt.Sprintf("%s.%s", netID, models.NetworkUser)),
-	// 		Name:      models.NetworkUser.String(),
-	// 		Default:   true,
-	// 		NetworkID: netID,
-	// 		RuleType:  models.UserPolicy,
-	// 		Src: []models.AclPolicyTag{
-	// 			{
-	// 				ID:    models.UserRoleAclID,
-	// 				Value: fmt.Sprintf("%s-%s", netID, models.NetworkUser),
-	// 			}},
-	// 		Dst: []models.AclPolicyTag{
-	// 			{
-	// 				ID:    models.DeviceAclID,
-	// 				Value: fmt.Sprintf("%s.%s", netID, models.RemoteAccessTagName),
-	// 			}},
-	// 		AllowedDirection: models.TrafficDirectionUni,
-	// 		Enabled:          true,
-	// 		CreatedBy:        "auto",
-	// 		CreatedAt:        time.Now().UTC(),
-	// 	}
-	// 	logic.InsertAcl(defaultUserAcl)
-	// }
-
-	if !logic.IsAclExists(models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin))) {
+
+	if !logic.IsAclExists(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin)) {
 		defaultUserAcl := models.Acl{
-			ID:        models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin)),
-			Name:      fmt.Sprintf("%s-grp", models.NetworkAdmin),
+			ID:        fmt.Sprintf("%s.%s-grp", netID, models.NetworkAdmin),
+			Name:      "Network Admin",
+			MetaData:  "This Policy allows all network admins to communicate with all remote access gateways",
 			Default:   true,
 			NetworkID: netID,
 			RuleType:  models.UserPolicy,
@@ -1175,10 +1167,11 @@ func CreateDefaultUserPolicies(netID models.NetworkID) {
 		logic.InsertAcl(defaultUserAcl)
 	}
 
-	if !logic.IsAclExists(models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser))) {
+	if !logic.IsAclExists(fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser)) {
 		defaultUserAcl := models.Acl{
-			ID:        models.AclID(fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser)),
-			Name:      fmt.Sprintf("%s-grp", models.NetworkUser),
+			ID:        fmt.Sprintf("%s.%s-grp", netID, models.NetworkUser),
+			Name:      "Network User",
+			MetaData:  "This Policy allows all network users to communicate with all remote access gateways",
 			Default:   true,
 			NetworkID: netID,
 			RuleType:  models.UserPolicy,