update egress domain model on acls

This commit is contained in:
abhishek9686 2025-08-19 13:05:46 +05:30
parent 4d3ceffc95
commit 0015357476
6 changed files with 283 additions and 97 deletions

View file

@ -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")
}

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/google/uuid"
@ -384,7 +383,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 {
@ -392,7 +390,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

View file

@ -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,
})
}
}
}
}
}
}
}

View file

@ -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,

View file

@ -92,28 +92,56 @@ func GetFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []
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 && 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,
})
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,
})
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 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{}{}
}
}

View file

@ -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"`