feat(remote-speakers): enhance remote speaker management and API integration
CI / changes (push) Successful in 8s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 25s
CI / web (push) Failing after 34s
CI / go (push) Failing after 19s
CI / bird2 (push) Has been skipped
CI / release (push) Has been skipped
CI / changes (push) Successful in 8s
CI / commitlint (push) Has been skipped
CI / openapi (push) Successful in 25s
CI / web (push) Failing after 34s
CI / go (push) Failing after 19s
CI / bird2 (push) Has been skipped
CI / release (push) Has been skipped
- Added support for remote speaker configuration in the README and documentation. - Implemented a new endpoint for retrieving the bundle signing public key. - Updated the `evobgp-agent` to include a `serve` command for Panel→Node sync API. - Enhanced CI workflow to validate remote speaker compose files. - Introduced new fields in the API and UI for managing speaker metadata, including dispatch status and sync status. - Improved error handling and response formatting in speaker-related API endpoints. - Updated documentation to reflect changes in remote speaker functionality and usage guidelines.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package pipeline
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"evobgp/internal/birdfmt"
|
||||
"evobgp/internal/store"
|
||||
)
|
||||
|
||||
// BirdLocalsForSpeaker merges tenant settings with per-speaker meta_json overrides.
|
||||
func BirdLocalsForSpeaker(st store.Backend, tenantID, speakerID string) birdLocals {
|
||||
loc := birdLocalsFromStore(st, tenantID)
|
||||
if st == nil || strings.TrimSpace(speakerID) == "" {
|
||||
return loc
|
||||
}
|
||||
sp, err := st.GetSpeaker(tenantID, speakerID)
|
||||
if err != nil || sp == nil {
|
||||
return loc
|
||||
}
|
||||
meta := store.ParseSpeakerMeta(sp.MetaJSON)
|
||||
if s := strings.TrimSpace(meta.BirdBgpSourceIPv4); s != "" {
|
||||
loc.routerID = s
|
||||
loc.localV4 = s
|
||||
}
|
||||
if s := strings.TrimSpace(meta.BirdBgpSourceIPv6); s != "" {
|
||||
loc.localV6 = s
|
||||
}
|
||||
return loc
|
||||
}
|
||||
|
||||
// OverlayFragmentsForSpeaker re-renders bird.conf and peers fragment with speaker-specific BIRD locals.
|
||||
func OverlayFragmentsForSpeaker(st store.Backend, tenantID, speakerID, revisionID string, frags map[string]string) (map[string]string, error) {
|
||||
if frags == nil {
|
||||
return nil, fmt.Errorf("pipeline: overlay: nil fragments")
|
||||
}
|
||||
locals := BirdLocalsForSpeaker(st, tenantID, speakerID)
|
||||
out := make(map[string]string, len(frags))
|
||||
for k, v := range frags {
|
||||
out[k] = v
|
||||
}
|
||||
moduleHint := "aggregate"
|
||||
if main := frags["bird.conf"]; main != "" {
|
||||
if idx := strings.Index(main, "trigger module "); idx >= 0 {
|
||||
rest := main[idx+len("trigger module "):]
|
||||
if end := strings.Index(rest, ")"); end > 0 {
|
||||
moduleHint = strings.TrimSpace(rest[:end])
|
||||
}
|
||||
}
|
||||
}
|
||||
main, err := birdfmt.RenderMainBirdConf(birdfmt.MainBirdConfOptions{
|
||||
RouterID: locals.routerID,
|
||||
Includes: birdfmt.StandardIncludeFragments(),
|
||||
Preamble: fmt.Sprintf("EvoBGP tenant aggregate config (trigger module %s) revision %s speaker %s", moduleHint, revisionID, speakerID),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out["bird.conf"] = main
|
||||
peersBody, err := renderPeersBirdFragment(st, tenantID, locals)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pPeers := birdfmt.FragmentIncludePath(birdfmt.FragmentPeers)
|
||||
out[pPeers] = peersBody
|
||||
return out, nil
|
||||
}
|
||||
Reference in New Issue
Block a user