feat: enhance BGP template and peer configuration handling. Introduce policies_json parameter for local IP and ASN overrides in BGP speakers. Implement BGP template rendering and update peer configuration to utilize templates, improving flexibility in BGP setup. Add tests for new rendering logic and ensure proper integration with existing configurations.
CI / changes (push) Successful in 6s
CI / openapi (push) Successful in 27s
CI / go (push) Successful in 23s
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 (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 1m1s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Successful in 1m26s
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Successful in 1m33s
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 1m25s
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Successful in 1m28s
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Successful in 1m21s
CI / changes (push) Successful in 6s
CI / openapi (push) Successful in 27s
CI / go (push) Successful in 23s
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 (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 1m1s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Successful in 1m26s
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Successful in 1m33s
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 1m25s
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Successful in 1m28s
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Successful in 1m21s
This commit is contained in:
@@ -236,6 +236,16 @@ func buildPreviewFragments(st store.Backend, tenantID, moduleID, revisionID stri
|
||||
staticV6 := birdfmt.RenderStaticIPv6Routes("evobgp_prefixes_v6", sr6)
|
||||
|
||||
locals := birdLocalsFromStore(st, tenantID)
|
||||
tplBody, err := birdfmt.RenderBGPTemplates(birdfmt.BGPTemplatesOptions{
|
||||
LocalIPv4: locals.localV4,
|
||||
LocalIPv6: locals.localV6,
|
||||
LocalASN: locals.localASN,
|
||||
ExportFilterV4: birdFilterNameV4,
|
||||
ExportFilterV6: birdFilterNameV6,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
peersBody, err := renderPeersBirdFragment(st, tenantID, locals)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -252,6 +262,7 @@ func buildPreviewFragments(st store.Backend, tenantID, moduleID, revisionID stri
|
||||
|
||||
p4 := birdfmt.FragmentIncludePath(birdfmt.FragmentFiltersV4)
|
||||
p6 := birdfmt.FragmentIncludePath(birdfmt.FragmentFiltersV6)
|
||||
pTpl := birdfmt.FragmentIncludePath(birdfmt.FragmentBGPTemplate)
|
||||
px4 := birdfmt.FragmentIncludePath(birdfmt.FragmentPrefixesV4)
|
||||
px6 := birdfmt.FragmentIncludePath(birdfmt.FragmentPrefixesV6)
|
||||
pPeers := birdfmt.FragmentIncludePath(birdfmt.FragmentPeers)
|
||||
@@ -260,6 +271,7 @@ func buildPreviewFragments(st store.Backend, tenantID, moduleID, revisionID stri
|
||||
"bird.conf": main,
|
||||
p4: birdfmt.JoinFragments(birdfmt.ManagedBanner(revisionID), f4),
|
||||
p6: birdfmt.JoinFragments(birdfmt.ManagedBanner(revisionID), f6),
|
||||
pTpl: birdfmt.JoinFragments(birdfmt.ManagedBanner(revisionID), tplBody),
|
||||
px4: birdfmt.JoinFragments(birdfmt.ManagedBanner(revisionID), staticV4),
|
||||
px6: birdfmt.JoinFragments(birdfmt.ManagedBanner(revisionID), staticV6),
|
||||
pPeers: peersBody,
|
||||
@@ -346,6 +358,30 @@ type peerPolicyJSON struct {
|
||||
LocalASN float64 `json:"local_asn"`
|
||||
}
|
||||
|
||||
func effectivePeerLocals(loc birdLocals, pol peerPolicyJSON) (v4, v6 string, asn uint32) {
|
||||
v4 = strings.TrimSpace(loc.localV4)
|
||||
v6 = strings.TrimSpace(loc.localV6)
|
||||
if s := strings.TrimSpace(pol.LocalIPv4); s != "" {
|
||||
v4 = s
|
||||
}
|
||||
if s := strings.TrimSpace(pol.LocalIPv6); s != "" {
|
||||
v6 = s
|
||||
}
|
||||
asn = loc.localASN
|
||||
if pol.LocalASN >= 1 && pol.LocalASN <= 4294967295 {
|
||||
asn = uint32(pol.LocalASN)
|
||||
}
|
||||
return v4, v6, asn
|
||||
}
|
||||
|
||||
// peerNeedsLocalOverride is true when the peer's effective local IP or ASN differs from tenant defaults in the BGP template.
|
||||
func peerNeedsLocalOverride(loc birdLocals, effLocal string, effASN uint32, ipv4 bool) bool {
|
||||
if ipv4 {
|
||||
return strings.TrimSpace(effLocal) != strings.TrimSpace(loc.localV4) || effASN != loc.localASN
|
||||
}
|
||||
return strings.TrimSpace(effLocal) != strings.TrimSpace(loc.localV6) || effASN != loc.localASN
|
||||
}
|
||||
|
||||
func renderPeersBirdFragment(st store.Backend, tenantID string, loc birdLocals) (string, error) {
|
||||
peers := st.ListPeers(tenantID)
|
||||
var parts []string
|
||||
@@ -362,29 +398,22 @@ func renderPeersBirdFragment(st store.Backend, tenantID string, loc birdLocals)
|
||||
continue
|
||||
}
|
||||
pol := parsePeerPolicies(p.PoliciesJSON)
|
||||
lv4 := loc.localV4
|
||||
if strings.TrimSpace(pol.LocalIPv4) != "" {
|
||||
lv4 = strings.TrimSpace(pol.LocalIPv4)
|
||||
}
|
||||
lv6 := loc.localV6
|
||||
if strings.TrimSpace(pol.LocalIPv6) != "" {
|
||||
lv6 = strings.TrimSpace(pol.LocalIPv6)
|
||||
}
|
||||
asn := loc.localASN
|
||||
if pol.LocalASN >= 1 && pol.LocalASN <= 4294967295 {
|
||||
asn = uint32(pol.LocalASN)
|
||||
}
|
||||
lv4, lv6, asn := effectivePeerLocals(loc, pol)
|
||||
proto := peerProtocolName(p.ID)
|
||||
ra := uint32(p.RemoteASN)
|
||||
if addr.Is4() {
|
||||
s, err := birdfmt.RenderProtocolBGPIPv4(birdfmt.BGPPeerIPv4Options{
|
||||
ProtocolName: proto,
|
||||
LocalIP: lv4,
|
||||
LocalASN: asn,
|
||||
NeighborIP: addr.String(),
|
||||
NeighborASN: ra,
|
||||
ExportFilter: birdFilterNameV4,
|
||||
})
|
||||
opts := birdfmt.BGPPeerFromTemplateOptions{
|
||||
ProtocolName: proto,
|
||||
TemplateName: birdfmt.BGPTemplateNameV4,
|
||||
NeighborIP: addr.String(),
|
||||
NeighborASN: ra,
|
||||
SourceAddress: lv4,
|
||||
}
|
||||
if peerNeedsLocalOverride(loc, lv4, asn, true) {
|
||||
opts.OverrideLocalIP = lv4
|
||||
opts.OverrideLocalASN = asn
|
||||
}
|
||||
s, err := birdfmt.RenderProtocolBGPFromTemplate(opts)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -392,14 +421,18 @@ func renderPeersBirdFragment(st store.Backend, tenantID string, loc birdLocals)
|
||||
continue
|
||||
}
|
||||
if addr.Is6() {
|
||||
s, err := birdfmt.RenderProtocolBGPIPv6(birdfmt.BGPPeerIPv6Options{
|
||||
ProtocolName: proto,
|
||||
LocalIP: lv6,
|
||||
LocalASN: asn,
|
||||
NeighborIP: addr.String(),
|
||||
NeighborASN: ra,
|
||||
ExportFilter: birdFilterNameV6,
|
||||
})
|
||||
opts := birdfmt.BGPPeerFromTemplateOptions{
|
||||
ProtocolName: proto,
|
||||
TemplateName: birdfmt.BGPTemplateNameV6,
|
||||
NeighborIP: addr.String(),
|
||||
NeighborASN: ra,
|
||||
SourceAddress: lv6,
|
||||
}
|
||||
if peerNeedsLocalOverride(loc, lv6, asn, false) {
|
||||
opts.OverrideLocalIP = lv6
|
||||
opts.OverrideLocalASN = asn
|
||||
}
|
||||
s, err := birdfmt.RenderProtocolBGPFromTemplate(opts)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user