feat: enhance EvoBGP with new command-line options for the evobgp-agent, including a watch command for periodic configuration updates. Update go.mod with additional dependencies and improve Docker Compose setup for new services, including NATS and various worker components.
This commit is contained in:
+81
-16
@@ -32,6 +32,15 @@ type Memory struct {
|
||||
|
||||
peers map[string]*BGPPeer
|
||||
|
||||
dohProfiles map[string]*DohProfile
|
||||
communities map[string]*Community
|
||||
cdnSources map[string]*CDNSource
|
||||
asEntries map[string]*ASEntry
|
||||
domainEnt map[string]*DomainEntry
|
||||
ipRanges map[string]*IPRangeEntry
|
||||
settings map[string]map[string]any // tenantID -> key -> JSON-compatible value
|
||||
revPrefixes map[string][]PrefixRow
|
||||
|
||||
// DemoIDs valid after SeedDemo()
|
||||
demoTenantID string
|
||||
demoModuleCDN string
|
||||
@@ -59,9 +68,10 @@ type Module struct {
|
||||
Enabled bool
|
||||
RefreshIntervalSec int // 0 = unset
|
||||
CronExpr string // optional cron for scheduler (display / future use)
|
||||
Priority int
|
||||
DefaultCommunityID *string
|
||||
DohProfileID *string
|
||||
Priority int
|
||||
DefaultCommunityID *string
|
||||
DohProfileID *string
|
||||
DeletedAt *time.Time
|
||||
}
|
||||
|
||||
type Revision struct {
|
||||
@@ -77,14 +87,17 @@ type Revision struct {
|
||||
PreviewFragments map[string]string
|
||||
}
|
||||
|
||||
// BGPPeer is a minimal stand-in until SQL-backed bgp_peer is wired into the API.
|
||||
// BGPPeer maps to bgp_peer (+ display fields in meta).
|
||||
type BGPPeer struct {
|
||||
ID string
|
||||
TenantID string
|
||||
SpeakerID *string
|
||||
Name string
|
||||
Neighbor string
|
||||
SessionState string // e.g. Established, Idle, Connect (intent or cached ops view)
|
||||
ID string
|
||||
TenantID string
|
||||
SpeakerID *string
|
||||
Name string
|
||||
Neighbor string
|
||||
RemoteASN int64
|
||||
Enabled bool
|
||||
SessionState string
|
||||
PoliciesJSON string
|
||||
}
|
||||
|
||||
type Speaker struct {
|
||||
@@ -93,6 +106,7 @@ type Speaker struct {
|
||||
Role string
|
||||
Endpoint string
|
||||
LastAppliedRevisionID *string
|
||||
MetaJSON string
|
||||
}
|
||||
|
||||
func NewMemory() *Memory {
|
||||
@@ -103,6 +117,14 @@ func NewMemory() *Memory {
|
||||
speakers: make(map[string]*Speaker),
|
||||
publishedRevision: make(map[string]publishedInfo),
|
||||
peers: make(map[string]*BGPPeer),
|
||||
dohProfiles: make(map[string]*DohProfile),
|
||||
communities: make(map[string]*Community),
|
||||
cdnSources: make(map[string]*CDNSource),
|
||||
asEntries: make(map[string]*ASEntry),
|
||||
domainEnt: make(map[string]*DomainEntry),
|
||||
ipRanges: make(map[string]*IPRangeEntry),
|
||||
settings: make(map[string]map[string]any),
|
||||
revPrefixes: make(map[string][]PrefixRow),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,6 +215,8 @@ protocol direct {
|
||||
SpeakerID: &sid,
|
||||
Name: "demo-upstream-4",
|
||||
Neighbor: "198.51.100.2",
|
||||
RemoteASN: 65001,
|
||||
Enabled: true,
|
||||
SessionState: "Established",
|
||||
}
|
||||
p2 := uuid.NewString()
|
||||
@@ -202,10 +226,20 @@ protocol direct {
|
||||
SpeakerID: &sid,
|
||||
Name: "demo-upstream-6",
|
||||
Neighbor: "2001:db8::2",
|
||||
RemoteASN: 65002,
|
||||
Enabled: true,
|
||||
SessionState: "Idle",
|
||||
}
|
||||
|
||||
m.demoTenantID, m.demoModuleCDN, m.demoModuleIP, m.demoRevisionID, m.demoSpeakerID = tid, mCDN, mIP, rid, sid
|
||||
|
||||
// Demo materialized prefixes for /revisions/{id}/prefixes
|
||||
cid := uuid.NewString()
|
||||
m.communities[cid] = &Community{ID: cid, TenantID: tid, Name: "demo-comm", Kind: "large", ValueJSON: "{}"}
|
||||
m.revPrefixes[rid] = []PrefixRow{
|
||||
{Prefix: "203.0.113.0/24", CommunityID: &cid, Source: "demo"},
|
||||
{Prefix: "2001:db8::/32", CommunityID: &cid, Source: "demo"},
|
||||
}
|
||||
}
|
||||
|
||||
// MaterializedPrefixStats returns max and sum of MaterializedPrefixCount across revisions.
|
||||
@@ -256,7 +290,7 @@ func (m *Memory) ListModules(tenantID string) []*Module {
|
||||
defer m.mu.RUnlock()
|
||||
var out []*Module
|
||||
for _, mod := range m.modules {
|
||||
if mod.TenantID == tenantID {
|
||||
if mod.TenantID == tenantID && mod.DeletedAt == nil {
|
||||
out = append(out, mod)
|
||||
}
|
||||
}
|
||||
@@ -287,7 +321,7 @@ func (m *Memory) GetModule(tenantID, moduleID string) (*Module, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
mod, ok := m.modules[moduleID]
|
||||
if !ok {
|
||||
if !ok || mod.DeletedAt != nil {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
if mod.TenantID != tenantID {
|
||||
@@ -388,6 +422,11 @@ func (m *Memory) CreateRollbackRevision(tenantID, sourceRevisionID string) (newI
|
||||
MaterializedPrefixCount: src.MaterializedPrefixCount,
|
||||
PreviewFragments: frag,
|
||||
}
|
||||
if px, ok := m.revPrefixes[sourceRevisionID]; ok {
|
||||
cp := make([]PrefixRow, len(px))
|
||||
copy(cp, px)
|
||||
m.revPrefixes[newID] = cp
|
||||
}
|
||||
return newID, nil
|
||||
}
|
||||
|
||||
@@ -423,8 +462,10 @@ func (m *Memory) PublishRevisionForSpeaker(speakerID, revisionID string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RevisionDiff returns a trivial JSON-friendly diff between prefix sets (empty for memory demo).
|
||||
// RevisionDiff returns prefix set diff from materialized snapshots when present.
|
||||
func (m *Memory) RevisionDiff(tenantID, aID, bID string) (map[string]any, error) {
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
_, err := m.getRevisionLocked(tenantID, aID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -433,13 +474,37 @@ func (m *Memory) RevisionDiff(tenantID, aID, bID string) (map[string]any, error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
setA := make(map[string]struct{})
|
||||
setB := make(map[string]struct{})
|
||||
for _, p := range m.revPrefixes[aID] {
|
||||
setA[p.Prefix] = struct{}{}
|
||||
}
|
||||
for _, p := range m.revPrefixes[bID] {
|
||||
setB[p.Prefix] = struct{}{}
|
||||
}
|
||||
var added, removed []string
|
||||
unchanged := 0
|
||||
for p := range setB {
|
||||
if _, ok := setA[p]; !ok {
|
||||
added = append(added, p)
|
||||
} else {
|
||||
unchanged++
|
||||
}
|
||||
}
|
||||
for p := range setA {
|
||||
if _, ok := setB[p]; !ok {
|
||||
removed = append(removed, p)
|
||||
}
|
||||
}
|
||||
sort.Strings(added)
|
||||
sort.Strings(removed)
|
||||
return map[string]any{
|
||||
"revision_a": aID,
|
||||
"revision_b": bID,
|
||||
"prefixes": map[string]any{
|
||||
"added": []string{},
|
||||
"removed": []string{},
|
||||
"unchanged_count": 0,
|
||||
"added": added,
|
||||
"removed": removed,
|
||||
"unchanged_count": unchanged,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user