feat: refactor materialization logic to group static routes by community in the refresh pipeline. Introduce a new structure for managing static routes, enhancing the handling of IPv4 and IPv6 routes while preserving community associations. Update related functions to support the new grouping mechanism.
CI / changes (push) Successful in 5s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 38s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Has been skipped
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Has been skipped
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Successful in 15s
CI / docker-go-prime (push) Successful in 24s
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 59s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Successful in 2m6s
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Successful in 1m22s
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Successful in 1m21s
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Successful in 1m24s
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Successful in 1m8s
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Successful in 1m23s
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Successful in 1m22s
CI / changes (push) Successful in 5s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 38s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Has been skipped
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Has been skipped
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Successful in 15s
CI / docker-go-prime (push) Successful in 24s
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 59s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Successful in 2m6s
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Successful in 1m22s
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Successful in 1m21s
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Successful in 1m24s
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Successful in 1m8s
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Successful in 1m23s
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Successful in 1m22s
This commit is contained in:
@@ -3,6 +3,7 @@ package pipeline
|
||||
import (
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -10,12 +11,18 @@ import (
|
||||
"evobgp/internal/store"
|
||||
)
|
||||
|
||||
// materializeRowsForBird turns prefix rows into export-filter CIDR lists, optional AS_PATH rules, and static routes with per-prefix communities.
|
||||
// Duplicate CIDRs: first occurrence wins for static community; filters use unique CIDRs.
|
||||
type staticCommunityRoutes struct {
|
||||
CommunityID string
|
||||
RoutesV4 []birdfmt.StaticRoute
|
||||
RoutesV6 []birdfmt.StaticRoute
|
||||
}
|
||||
|
||||
// materializeRowsForBird turns prefix rows into export-filter CIDR lists, optional AS_PATH rules,
|
||||
// and static routes grouped by community. The same prefix can appear in multiple community groups.
|
||||
func materializeRowsForBird(st store.Backend, tenantID string, rows []store.PrefixRow) (
|
||||
filterV4, filterV6 []netip.Prefix,
|
||||
pathASNs []int64,
|
||||
staticV4, staticV6 []birdfmt.StaticRoute,
|
||||
staticByCommunity []staticCommunityRoutes,
|
||||
err error,
|
||||
) {
|
||||
var pathSeen map[int64]struct{}
|
||||
@@ -31,7 +38,12 @@ func materializeRowsForBird(st store.Backend, tenantID string, rows []store.Pref
|
||||
}
|
||||
|
||||
filterSeen := make(map[string]struct{})
|
||||
staticChosen := make(map[string]birdfmt.StaticRoute)
|
||||
type staticGroup struct {
|
||||
v4 map[string]birdfmt.StaticRoute
|
||||
v6 map[string]birdfmt.StaticRoute
|
||||
}
|
||||
staticGroups := make(map[string]*staticGroup)
|
||||
routeBodyByCommunity := make(map[string]string)
|
||||
|
||||
for _, pr := range rows {
|
||||
p := strings.TrimSpace(pr.Prefix)
|
||||
@@ -58,24 +70,67 @@ func materializeRowsForBird(st store.Backend, tenantID string, rows []store.Pref
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := staticChosen[key]; ok {
|
||||
continue
|
||||
communityID := ""
|
||||
if pr.CommunityID != nil {
|
||||
communityID = strings.TrimSpace(*pr.CommunityID)
|
||||
}
|
||||
body, err := communityRouteBody(st, tenantID, pr.CommunityID)
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, nil, err
|
||||
body, ok := routeBodyByCommunity[communityID]
|
||||
if !ok {
|
||||
body, err = communityRouteBody(st, tenantID, pr.CommunityID)
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
routeBodyByCommunity[communityID] = body
|
||||
}
|
||||
grp, ok := staticGroups[communityID]
|
||||
if !ok {
|
||||
grp = &staticGroup{
|
||||
v4: make(map[string]birdfmt.StaticRoute),
|
||||
v6: make(map[string]birdfmt.StaticRoute),
|
||||
}
|
||||
staticGroups[communityID] = grp
|
||||
}
|
||||
if pfx.Addr().Is4() {
|
||||
if _, exists := grp.v4[key]; !exists {
|
||||
grp.v4[key] = birdfmt.StaticRoute{Prefix: pfx, RouteBody: body}
|
||||
}
|
||||
} else if pfx.Addr().Is6() {
|
||||
if _, exists := grp.v6[key]; !exists {
|
||||
grp.v6[key] = birdfmt.StaticRoute{Prefix: pfx, RouteBody: body}
|
||||
}
|
||||
}
|
||||
staticChosen[key] = birdfmt.StaticRoute{Prefix: pfx, RouteBody: body}
|
||||
}
|
||||
|
||||
for _, sr := range staticChosen {
|
||||
if sr.Prefix.Addr().Is4() {
|
||||
staticV4 = append(staticV4, sr)
|
||||
} else if sr.Prefix.Addr().Is6() {
|
||||
staticV6 = append(staticV6, sr)
|
||||
}
|
||||
groupKeys := make([]string, 0, len(staticGroups))
|
||||
for k := range staticGroups {
|
||||
groupKeys = append(groupKeys, k)
|
||||
}
|
||||
return filterV4, filterV6, pathASNs, staticV4, staticV6, nil
|
||||
sort.Strings(groupKeys)
|
||||
|
||||
for _, gid := range groupKeys {
|
||||
grp := staticGroups[gid]
|
||||
out := staticCommunityRoutes{CommunityID: gid}
|
||||
|
||||
v4Keys := make([]string, 0, len(grp.v4))
|
||||
for k := range grp.v4 {
|
||||
v4Keys = append(v4Keys, k)
|
||||
}
|
||||
sort.Strings(v4Keys)
|
||||
for _, k := range v4Keys {
|
||||
out.RoutesV4 = append(out.RoutesV4, grp.v4[k])
|
||||
}
|
||||
|
||||
v6Keys := make([]string, 0, len(grp.v6))
|
||||
for k := range grp.v6 {
|
||||
v6Keys = append(v6Keys, k)
|
||||
}
|
||||
sort.Strings(v6Keys)
|
||||
for _, k := range v6Keys {
|
||||
out.RoutesV6 = append(out.RoutesV6, grp.v6[k])
|
||||
}
|
||||
staticByCommunity = append(staticByCommunity, out)
|
||||
}
|
||||
return filterV4, filterV6, pathASNs, staticByCommunity, nil
|
||||
}
|
||||
|
||||
func communityRouteBody(st store.Backend, tenantID string, cid *string) (string, error) {
|
||||
|
||||
Reference in New Issue
Block a user