Pārlūkot izejas kodu

update egress domain model on acls

abhishek9686 3 nedēļas atpakaļ
vecāks
revīzija
e9efead01b
6 mainītis faili ar 284 papildinājumiem un 98 dzēšanām
  1. 45 3
      controllers/egress.go
  2. 1 3
      controllers/hosts.go
  3. 59 24
      logic/acls.go
  4. 12 2
      logic/egress.go
  5. 157 57
      pro/logic/acls.go
  6. 10 9
      schema/egress.go

+ 45 - 3
controllers/egress.go

@@ -74,6 +74,7 @@ func createEgress(w http.ResponseWriter, r *http.Request) {
 		Description: req.Description,
 		Range:       egressRange,
 		Domain:      req.Domain,
+		DomainAns:   []string{},
 		Nat:         req.Nat,
 		Nodes:       make(datatypes.JSONMap),
 		Tags:        make(datatypes.JSONMap),
@@ -203,14 +204,25 @@ func updateEgress(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	var egressRange string
+	var cidrErr error
 	if !req.IsInetGw {
-		egressRange, err = logic.NormalizeCIDR(req.Range)
-		if err != nil {
-			logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		egressRange, cidrErr = logic.NormalizeCIDR(req.Range)
+		isDomain := logic.IsFQDN(req.Range)
+		if cidrErr != nil && !isDomain {
+			if cidrErr != nil {
+				logic.ReturnErrorResponse(w, r, logic.FormatError(cidrErr, "badrequest"))
+			} else {
+				logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("bad domain name"), "badrequest"))
+			}
 			return
 		}
+		if isDomain {
+			req.Domain = req.Range
+			egressRange = ""
+		}
 	} else {
 		egressRange = "*"
+		req.Domain = ""
 	}
 
 	e := schema.Egress{ID: req.ID}
@@ -255,6 +267,7 @@ func updateEgress(w http.ResponseWriter, r *http.Request) {
 	e.Description = req.Description
 	e.Name = req.Name
 	e.Nat = req.Nat
+	e.Domain = req.Domain
 	e.Status = req.Status
 	e.UpdatedAt = time.Now().UTC()
 	if err := logic.ValidateEgressReq(&e); err != nil {
@@ -280,6 +293,35 @@ func updateEgress(w http.ResponseWriter, r *http.Request) {
 	}
 	event.Diff.New = e
 	logic.LogEvent(event)
+	if req.Domain != "" {
+		if req.Nodes != nil {
+			for nodeID := range req.Nodes {
+				node, err := logic.GetNodeByID(nodeID)
+				if err != nil {
+					continue
+				}
+				host, _ := logic.GetHost(node.HostID.String())
+				if host == nil {
+					continue
+				}
+				fmt.Println("=======> Sending Host Update: ", host.Name)
+				mq.HostUpdate(&models.HostUpdate{
+					Action: models.EgressUpdate,
+					Host:   *host,
+					EgressDomain: models.EgressDomain{
+						ID:     e.ID,
+						Host:   *host,
+						Node:   node,
+						Domain: e.Domain,
+					},
+					Node: node,
+				})
+			}
+		}
+
+	} else {
+		go mq.PublishPeerUpdate(false)
+	}
 	go mq.PublishPeerUpdate(false)
 	logic.ReturnSuccessResponseWithJson(w, r, e, "updated egress resource")
 }

+ 1 - 3
controllers/hosts.go

@@ -5,7 +5,6 @@ import (
 	"errors"
 	"fmt"
 	"net/http"
-	"strings"
 	"time"
 
 	"github.com/google/uuid"
@@ -393,7 +392,6 @@ func hostUpdateFallback(w http.ResponseWriter, r *http.Request) {
 	case models.UpdateMetrics:
 		mq.UpdateMetricsFallBack(hostUpdate.Node.ID.String(), hostUpdate.NewMetrics)
 	case models.EgressUpdate:
-		fmt.Println("=====> Recv Egress Update: ", hostUpdate.Node.EgressGatewayRanges)
 		e := schema.Egress{ID: hostUpdate.EgressDomain.ID}
 		err = e.Get(db.WithContext(r.Context()))
 		if err != nil {
@@ -401,7 +399,7 @@ func hostUpdateFallback(w http.ResponseWriter, r *http.Request) {
 			return
 		}
 		if len(hostUpdate.Node.EgressGatewayRanges) > 0 {
-			e.Range = strings.Join(hostUpdate.Node.EgressGatewayRanges, ",")
+			e.DomainAns = hostUpdate.Node.EgressGatewayRanges
 			e.Update(db.WithContext(r.Context()))
 		}
 		sendPeerUpdate = true

+ 59 - 24
logic/acls.go

@@ -273,35 +273,70 @@ func getFwRulesForNodeAndPeerOnGw(node, peer models.Node, allowedPolicies []mode
 				if err != nil {
 					continue
 				}
-				dstI.Value = e.Range
+				if len(e.DomainAns) > 0 {
+					for _, domainAnsI := range e.DomainAns {
+						dstI.Value = domainAnsI
+
+						ip, cidr, err := net.ParseCIDR(dstI.Value)
+						if err == nil {
+							if ip.To4() != nil {
+								if node.Address.IP != nil {
+									rules = append(rules, models.FwRule{
+										SrcIP: net.IPNet{
+											IP:   node.Address.IP,
+											Mask: net.CIDRMask(32, 32),
+										},
+										DstIP: *cidr,
+										Allow: true,
+									})
+								}
+							} else {
+								if node.Address6.IP != nil {
+									rules = append(rules, models.FwRule{
+										SrcIP: net.IPNet{
+											IP:   node.Address6.IP,
+											Mask: net.CIDRMask(128, 128),
+										},
+										DstIP: *cidr,
+										Allow: true,
+									})
+								}
+							}
 
-				ip, cidr, err := net.ParseCIDR(dstI.Value)
-				if err == nil {
-					if ip.To4() != nil {
-						if node.Address.IP != nil {
-							rules = append(rules, models.FwRule{
-								SrcIP: net.IPNet{
-									IP:   node.Address.IP,
-									Mask: net.CIDRMask(32, 32),
-								},
-								DstIP: *cidr,
-								Allow: true,
-							})
-						}
-					} else {
-						if node.Address6.IP != nil {
-							rules = append(rules, models.FwRule{
-								SrcIP: net.IPNet{
-									IP:   node.Address6.IP,
-									Mask: net.CIDRMask(128, 128),
-								},
-								DstIP: *cidr,
-								Allow: true,
-							})
 						}
 					}
+				} else {
+					dstI.Value = e.Range
+
+					ip, cidr, err := net.ParseCIDR(dstI.Value)
+					if err == nil {
+						if ip.To4() != nil {
+							if node.Address.IP != nil {
+								rules = append(rules, models.FwRule{
+									SrcIP: net.IPNet{
+										IP:   node.Address.IP,
+										Mask: net.CIDRMask(32, 32),
+									},
+									DstIP: *cidr,
+									Allow: true,
+								})
+							}
+						} else {
+							if node.Address6.IP != nil {
+								rules = append(rules, models.FwRule{
+									SrcIP: net.IPNet{
+										IP:   node.Address6.IP,
+										Mask: net.CIDRMask(128, 128),
+									},
+									DstIP: *cidr,
+									Allow: true,
+								})
+							}
+						}
 
+					}
 				}
+
 			}
 		}
 	}

+ 12 - 2
logic/egress.go

@@ -107,7 +107,12 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node, eli []schema.Egr
 				m64 = 256
 			}
 			m := uint32(m64)
-			req.Ranges = append(req.Ranges, e.Range)
+			if e.Range != "" {
+				req.Ranges = append(req.Ranges, e.Range)
+			} else {
+				req.Ranges = append(req.Ranges, e.DomainAns...)
+			}
+
 			req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 				Network:     e.Range,
 				Nat:         e.Nat,
@@ -149,7 +154,12 @@ func GetNodeEgressInfo(targetNode *models.Node, eli []schema.Egress, acls []mode
 				m64 = 256
 			}
 			m := uint32(m64)
-			req.Ranges = append(req.Ranges, e.Range)
+			if e.Range != "" {
+				req.Ranges = append(req.Ranges, e.Range)
+			} else {
+				req.Ranges = append(req.Ranges, e.DomainAns...)
+			}
+
 			req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 				Network:     e.Range,
 				Nat:         e.Nat,

+ 157 - 57
pro/logic/acls.go

@@ -92,28 +92,56 @@ func GetFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []
 							if err != nil {
 								continue
 							}
-							dstI.Value = e.Range
-
-							ip, cidr, err := net.ParseCIDR(dstI.Value)
-							if err == nil {
-								if ip.To4() != nil && userNodeI.StaticNode.Address != "" {
-									rules = append(rules, models.FwRule{
-										SrcIP:           userNodeI.StaticNode.AddressIPNet4(),
-										DstIP:           *cidr,
-										AllowedProtocol: policy.Proto,
-										AllowedPorts:    policy.Port,
-										Allow:           true,
-									})
-								} else if ip.To16() != nil && userNodeI.StaticNode.Address6 != "" {
-									rules = append(rules, models.FwRule{
-										SrcIP:           userNodeI.StaticNode.AddressIPNet6(),
-										DstIP:           *cidr,
-										AllowedProtocol: policy.Proto,
-										AllowedPorts:    policy.Port,
-										Allow:           true,
-									})
+							if e.Range != "" {
+								dstI.Value = e.Range
+
+								ip, cidr, err := net.ParseCIDR(dstI.Value)
+								if err == nil {
+									if ip.To4() != nil && userNodeI.StaticNode.Address != "" {
+										rules = append(rules, models.FwRule{
+											SrcIP:           userNodeI.StaticNode.AddressIPNet4(),
+											DstIP:           *cidr,
+											AllowedProtocol: policy.Proto,
+											AllowedPorts:    policy.Port,
+											Allow:           true,
+										})
+									} else if ip.To16() != nil && userNodeI.StaticNode.Address6 != "" {
+										rules = append(rules, models.FwRule{
+											SrcIP:           userNodeI.StaticNode.AddressIPNet6(),
+											DstIP:           *cidr,
+											AllowedProtocol: policy.Proto,
+											AllowedPorts:    policy.Port,
+											Allow:           true,
+										})
+									}
+								}
+							} else if len(e.DomainAns) > 0 {
+								for _, domainAns := range e.DomainAns {
+									dstI.Value = domainAns
+
+									ip, cidr, err := net.ParseCIDR(dstI.Value)
+									if err == nil {
+										if ip.To4() != nil && userNodeI.StaticNode.Address != "" {
+											rules = append(rules, models.FwRule{
+												SrcIP:           userNodeI.StaticNode.AddressIPNet4(),
+												DstIP:           *cidr,
+												AllowedProtocol: policy.Proto,
+												AllowedPorts:    policy.Port,
+												Allow:           true,
+											})
+										} else if ip.To16() != nil && userNodeI.StaticNode.Address6 != "" {
+											rules = append(rules, models.FwRule{
+												SrcIP:           userNodeI.StaticNode.AddressIPNet6(),
+												DstIP:           *cidr,
+												AllowedProtocol: policy.Proto,
+												AllowedPorts:    policy.Port,
+												Allow:           true,
+											})
+										}
+									}
 								}
 							}
+
 						}
 					}
 
@@ -261,39 +289,78 @@ func GetFwRulesForNodeAndPeerOnGw(node, peer models.Node, allowedPolicies []mode
 				if err != nil {
 					continue
 				}
-				dstI.Value = e.Range
+				if e.Range != "" {
+					dstI.Value = e.Range
 
-				ip, cidr, err := net.ParseCIDR(dstI.Value)
-				if err == nil {
-					if ip.To4() != nil {
-						if node.Address.IP != nil {
-							rules = append(rules, models.FwRule{
-								SrcIP: net.IPNet{
-									IP:   node.Address.IP,
-									Mask: net.CIDRMask(32, 32),
-								},
-								DstIP:           *cidr,
-								AllowedProtocol: policy.Proto,
-								AllowedPorts:    policy.Port,
-								Allow:           true,
-							})
-						}
-					} else {
-						if node.Address6.IP != nil {
-							rules = append(rules, models.FwRule{
-								SrcIP: net.IPNet{
-									IP:   node.Address6.IP,
-									Mask: net.CIDRMask(128, 128),
-								},
-								DstIP:           *cidr,
-								AllowedProtocol: policy.Proto,
-								AllowedPorts:    policy.Port,
-								Allow:           true,
-							})
+					ip, cidr, err := net.ParseCIDR(dstI.Value)
+					if err == nil {
+						if ip.To4() != nil {
+							if node.Address.IP != nil {
+								rules = append(rules, models.FwRule{
+									SrcIP: net.IPNet{
+										IP:   node.Address.IP,
+										Mask: net.CIDRMask(32, 32),
+									},
+									DstIP:           *cidr,
+									AllowedProtocol: policy.Proto,
+									AllowedPorts:    policy.Port,
+									Allow:           true,
+								})
+							}
+						} else {
+							if node.Address6.IP != nil {
+								rules = append(rules, models.FwRule{
+									SrcIP: net.IPNet{
+										IP:   node.Address6.IP,
+										Mask: net.CIDRMask(128, 128),
+									},
+									DstIP:           *cidr,
+									AllowedProtocol: policy.Proto,
+									AllowedPorts:    policy.Port,
+									Allow:           true,
+								})
+							}
 						}
+
 					}
+				} else if len(e.DomainAns) > 0 {
+					for _, domainAnsI := range e.DomainAns {
+						dstI.Value = domainAnsI
 
+						ip, cidr, err := net.ParseCIDR(dstI.Value)
+						if err == nil {
+							if ip.To4() != nil {
+								if node.Address.IP != nil {
+									rules = append(rules, models.FwRule{
+										SrcIP: net.IPNet{
+											IP:   node.Address.IP,
+											Mask: net.CIDRMask(32, 32),
+										},
+										DstIP:           *cidr,
+										AllowedProtocol: policy.Proto,
+										AllowedPorts:    policy.Port,
+										Allow:           true,
+									})
+								}
+							} else {
+								if node.Address6.IP != nil {
+									rules = append(rules, models.FwRule{
+										SrcIP: net.IPNet{
+											IP:   node.Address6.IP,
+											Mask: net.CIDRMask(128, 128),
+										},
+										DstIP:           *cidr,
+										AllowedProtocol: policy.Proto,
+										AllowedPorts:    policy.Port,
+										Allow:           true,
+									})
+								}
+							}
+
+						}
+					}
 				}
+
 			}
 		}
 	}
@@ -958,7 +1025,14 @@ func getEgressUserRulesForNode(targetnode *models.Node,
 			continue
 		}
 		if _, ok := egI.Nodes[targetnode.ID.String()]; ok {
-			targetNodeTags[models.TagID(egI.Range)] = struct{}{}
+			if egI.Range != "" {
+				targetNodeTags[models.TagID(egI.Range)] = struct{}{}
+			} else if len(egI.DomainAns) > 0 {
+				for _, domainAnsI := range egI.DomainAns {
+					targetNodeTags[models.TagID(domainAnsI)] = struct{}{}
+				}
+			}
+
 			targetNodeTags[models.TagID(egI.ID)] = struct{}{}
 		}
 	}
@@ -976,7 +1050,14 @@ func getEgressUserRulesForNode(targetnode *models.Node,
 						for nodeID := range e.Nodes {
 							dstTags[nodeID] = struct{}{}
 						}
-						dstTags[e.Range] = struct{}{}
+						if e.Range != "" {
+							dstTags[e.Range] = struct{}{}
+						} else if len(e.DomainAns) > 0 {
+							for _, domainAnsI := range e.DomainAns {
+								dstTags[domainAnsI] = struct{}{}
+							}
+						}
+
 					}
 				}
 			}
@@ -1070,15 +1151,28 @@ func getEgressUserRulesForNode(targetnode *models.Node,
 						if err != nil {
 							continue
 						}
+						if e.Range != "" {
+							ip, cidr, err := net.ParseCIDR(e.Range)
+							if err == nil {
+								if ip.To4() != nil {
+									r.Dst = append(r.Dst, *cidr)
+								} else {
+									r.Dst6 = append(r.Dst6, *cidr)
+								}
 
-						ip, cidr, err := net.ParseCIDR(e.Range)
-						if err == nil {
-							if ip.To4() != nil {
-								r.Dst = append(r.Dst, *cidr)
-							} else {
-								r.Dst6 = append(r.Dst6, *cidr)
 							}
+						} else if len(e.DomainAns) > 0 {
+							for _, domainAnsI := range e.DomainAns {
+								ip, cidr, err := net.ParseCIDR(domainAnsI)
+								if err == nil {
+									if ip.To4() != nil {
+										r.Dst = append(r.Dst, *cidr)
+									} else {
+										r.Dst6 = append(r.Dst6, *cidr)
+									}
 
+								}
+							}
 						}
 
 					}
@@ -1593,7 +1687,13 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 			continue
 		}
 		if _, ok := egI.Nodes[targetnode.ID.String()]; ok {
-			targetNodeTags[models.TagID(egI.Range)] = struct{}{}
+			if egI.Range != "" {
+				targetNodeTags[models.TagID(egI.Range)] = struct{}{}
+			} else if len(egI.DomainAns) > 0 {
+				for _, domainAnsI := range egI.DomainAns {
+					targetNodeTags[models.TagID(domainAnsI)] = struct{}{}
+				}
+			}
 			targetNodeTags[models.TagID(egI.ID)] = struct{}{}
 		}
 	}

+ 10 - 9
schema/egress.go

@@ -11,15 +11,16 @@ import (
 const egressTable = "egresses"
 
 type Egress struct {
-	ID          string            `gorm:"primaryKey" json:"id"`
-	Name        string            `gorm:"name" json:"name"`
-	Network     string            `gorm:"network" json:"network"`
-	Description string            `gorm:"description" json:"description"`
-	Nodes       datatypes.JSONMap `gorm:"nodes" json:"nodes"`
-	Tags        datatypes.JSONMap `gorm:"tags" json:"tags"`
-	Range       string            `gorm:"range" json:"range"`
-	Domain      string            `gorm:"domain" json:"domain"`
-	Nat         bool              `gorm:"nat" json:"nat"`
+	ID          string                      `gorm:"primaryKey" json:"id"`
+	Name        string                      `gorm:"name" json:"name"`
+	Network     string                      `gorm:"network" json:"network"`
+	Description string                      `gorm:"description" json:"description"`
+	Nodes       datatypes.JSONMap           `gorm:"nodes" json:"nodes"`
+	Tags        datatypes.JSONMap           `gorm:"tags" json:"tags"`
+	Range       string                      `gorm:"range" json:"range"`
+	DomainAns   datatypes.JSONSlice[string] `gorm:"domain_ans" json:"domain_ans"`
+	Domain      string                      `gorm:"domain" json:"domain"`
+	Nat         bool                        `gorm:"nat" json:"nat"`
 	//IsInetGw    bool              `gorm:"is_inet_gw" json:"is_internet_gateway"`
 	Status    bool      `gorm:"status" json:"status"`
 	CreatedBy string    `gorm:"created_by" json:"created_by"`