Bläddra i källkod

add support for egress ranges on acl policy

abhishek9686 6 månader sedan
förälder
incheckning
0702a3db2e
2 ändrade filer med 123 tillägg och 84 borttagningar
  1. 34 0
      controllers/network.go
  2. 89 84
      logic/acls.go

+ 34 - 0
controllers/network.go

@@ -41,6 +41,7 @@ func networkHandlers(r *mux.Router) {
 		Methods(http.MethodPut)
 	r.HandleFunc("/api/networks/{networkname}/acls", logic.SecurityCheck(true, http.HandlerFunc(getNetworkACL))).
 		Methods(http.MethodGet)
+	r.HandleFunc("/api/networks/{networkname}/egress_routes", logic.SecurityCheck(true, http.HandlerFunc(getNetworkEgressRoutes)))
 }
 
 // @Summary     Lists all networks
@@ -429,6 +430,39 @@ func getNetworkACL(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(networkACL)
 }
 
+// @Summary     Get a network Egress routes
+// @Router      /api/networks/{networkname}/egress_routes [get]
+// @Tags        Networks
+// @Security    oauth
+// @Param       networkname path string true "Network name"
+// @Produce     json
+// @Success     200 {object} acls.SuccessResponse
+// @Failure     500 {object} models.ErrorResponse
+func getNetworkEgressRoutes(w http.ResponseWriter, r *http.Request) {
+	var params = mux.Vars(r)
+	netname := params["networkname"]
+	// check if network exists
+	_, err := logic.GetNetwork(netname)
+	if err != nil {
+		logger.Log(0, r.Header.Get("user"),
+			fmt.Sprintf("failed to fetch ACLs for network [%s]: %v", netname, err))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	nodes, err := logic.GetNetworkNodes(netname)
+	if err != nil {
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+	egressRoutes := []string{}
+	for _, node := range nodes {
+		if node.IsEgressGateway {
+			egressRoutes = append(egressRoutes, node.EgressGatewayRanges...)
+		}
+	}
+	logic.ReturnSuccessResponseWithJson(w, r, egressRoutes, "fetched network egress routes")
+}
+
 // @Summary     Delete a network
 // @Router      /api/networks/{networkname} [delete]
 // @Tags        Networks

+ 89 - 84
logic/acls.go

@@ -222,6 +222,83 @@ func IsAclExists(aclID string) bool {
 	_, err := GetAcl(aclID)
 	return err == nil
 }
+func GetEgressRanges(netID models.NetworkID) ([]string, map[string]struct{}, error) {
+
+	var result []string
+	resultMap := make(map[string]struct{})
+	networkNodes, err := GetNetworkNodes(netID.String())
+	if err != nil {
+		return []string{}, nil, err
+	}
+	for _, currentNode := range networkNodes {
+		if currentNode.Network != netID.String() {
+			continue
+		}
+		if currentNode.IsEgressGateway { // add the egress gateway range(s) to the result
+			if len(currentNode.EgressGatewayRanges) > 0 {
+				result = append(result, currentNode.EgressGatewayRanges...)
+				for _, egressRangeI := range currentNode.EgressGatewayRanges {
+					resultMap[egressRangeI] = struct{}{}
+				}
+			}
+		}
+	}
+	extclients, _ := GetNetworkExtClients(netID.String())
+	for _, extclient := range extclients {
+		if len(extclient.ExtraAllowedIPs) > 0 {
+			result = append(result, extclient.ExtraAllowedIPs...)
+			for _, extraAllowedIP := range extclient.ExtraAllowedIPs {
+				resultMap[extraAllowedIP] = struct{}{}
+			}
+		}
+	}
+	return result, resultMap, nil
+}
+
+func checkIfAclTagisValid(t models.AclPolicyTag, netID models.NetworkID) bool {
+	switch t.ID {
+	case models.NodeTagID:
+		// check if tag is valid
+		_, err := GetTag(models.TagID(t.Value))
+		if err != nil {
+			return false
+		}
+	case models.NodeID:
+		_, nodeErr := GetNodeByID(t.Value)
+		if nodeErr != nil {
+			_, staticNodeErr := GetExtClient(t.Value, netID.String())
+			if staticNodeErr != nil {
+				return false
+			}
+		}
+	case models.EgressRange:
+		_, rangesMap, err := GetEgressRanges(netID)
+		if err != nil {
+			return false
+		}
+		if _, ok := rangesMap[t.Value]; !ok {
+			return false
+		}
+	case models.UserAclID:
+		_, err := GetUser(t.Value)
+		if err != nil {
+			return false
+		}
+	case models.UserGroupAclID:
+		err := IsGroupValid(models.UserGroupID(t.Value))
+		if err != nil {
+			return false
+		}
+		// check if group belongs to this network
+		netGrps := GetUserGroupsInNetwork(netID)
+		if _, ok := netGrps[models.UserGroupID(t.Value)]; !ok {
+			return false
+		}
+	default:
+		return false
+	}
+	return true
+}
 
 // IsAclPolicyValid - validates if acl policy is valid
 func IsAclPolicyValid(acl models.Acl) bool {
@@ -235,115 +312,43 @@ func IsAclPolicyValid(acl models.Acl) bool {
 		// src list should only contain users
 		for _, srcI := range acl.Src {
 
-			if srcI.ID == "" || srcI.Value == "" {
-				return false
-			}
 			if srcI.Value == "*" {
 				continue
 			}
-			if srcI.ID != models.UserAclID && srcI.ID != models.UserGroupAclID {
-				return false
-			}
 			// check if user group is valid
-			if srcI.ID == models.UserAclID {
-				_, err := GetUser(srcI.Value)
-				if err != nil {
-					return false
-				}
-
-			} else if srcI.ID == models.UserGroupAclID {
-				err := IsGroupValid(models.UserGroupID(srcI.Value))
-				if err != nil {
-					return false
-				}
-				// check if group belongs to this network
-				netGrps := GetUserGroupsInNetwork(acl.NetworkID)
-				if _, ok := netGrps[models.UserGroupID(srcI.Value)]; !ok {
-					return false
-				}
+			if !checkIfAclTagisValid(srcI, acl.NetworkID) {
+				return false
 			}
-
 		}
 		for _, dstI := range acl.Dst {
 
-			if dstI.ID == "" || dstI.Value == "" {
-				return false
-			}
-			if dstI.ID != models.NodeTagID && dstI.ID != models.NodeID {
-				return false
-			}
 			if dstI.Value == "*" {
 				continue
 			}
-			if dstI.ID == models.NodeTagID {
-				// check if tag is valid
-				_, err := GetTag(models.TagID(dstI.Value))
-				if err != nil {
-					return false
-				}
-			} else {
-				_, nodeErr := GetNodeByID(dstI.Value)
-				if nodeErr != nil {
-					_, staticNodeErr := GetExtClient(dstI.Value, acl.NetworkID.String())
-					if staticNodeErr != nil {
-						return false
-					}
-				}
+
+			// check if user group is valid
+			if !checkIfAclTagisValid(dstI, acl.NetworkID) {
+				return false
 			}
 		}
 	case models.DevicePolicy:
 		for _, srcI := range acl.Src {
-			if srcI.ID == "" || srcI.Value == "" {
-				return false
-			}
-			if srcI.ID != models.NodeTagID && srcI.ID != models.NodeID {
-				return false
-			}
 			if srcI.Value == "*" {
 				continue
 			}
-			if srcI.ID == models.NodeTagID {
-				// check if tag is valid
-				_, err := GetTag(models.TagID(srcI.Value))
-				if err != nil {
-					return false
-				}
-			} else {
-				_, nodeErr := GetNodeByID(srcI.Value)
-				if nodeErr != nil {
-					_, staticNodeErr := GetExtClient(srcI.Value, acl.NetworkID.String())
-					if staticNodeErr != nil {
-						return false
-					}
-				}
+			// check if user group is valid
+			if !checkIfAclTagisValid(srcI, acl.NetworkID) {
+				return false
 			}
-
 		}
 		for _, dstI := range acl.Dst {
 
-			if dstI.ID == "" || dstI.Value == "" {
-				return false
-			}
-			if dstI.ID != models.NodeTagID && dstI.ID != models.NodeID {
-				return false
-			}
 			if dstI.Value == "*" {
 				continue
 			}
-			if dstI.ID == models.NodeTagID {
-				// check if tag is valid
-				_, err := GetTag(models.TagID(dstI.Value))
-				if err != nil {
-					return false
-				}
-			} else {
-				_, nodeErr := GetNodeByID(dstI.Value)
-				if nodeErr != nil {
-					_, staticNodeErr := GetExtClient(dstI.Value, acl.NetworkID.String())
-					if staticNodeErr != nil {
-						return false
-					}
-				}
+			// check if user group is valid
+			if !checkIfAclTagisValid(dstI, acl.NetworkID) {
+				return false
 			}
 		}
 	}