feat: implement peer reconciliation job for BGP peers
CI / changes (push) Successful in 7s
CI / openapi (push) Successful in 23s
CI / go (push) Failing after 30s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Successful in 1m5s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Successful in 1m3s
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / docker-go-prime (push) Has been skipped
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Has been skipped
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Has been skipped
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Has been skipped
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Has been skipped
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Has been skipped
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Has been skipped
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Has been skipped
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Has been skipped
CI / changes (push) Successful in 7s
CI / openapi (push) Successful in 23s
CI / go (push) Failing after 30s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Successful in 1m5s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Successful in 1m3s
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / docker-go-prime (push) Has been skipped
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Has been skipped
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Has been skipped
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Has been skipped
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Has been skipped
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Has been skipped
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Has been skipped
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Has been skipped
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Has been skipped
Added a new job type `peer_reconcile` to handle fast reconciliation of BGP peers without module ingestion. Updated API documentation to reflect the new job's functionality and its automatic application to speakers post-reconciliation. Enhanced the HTTP API to enqueue reconciliation jobs during peer creation, updates, and deletions, ensuring efficient state management for BGP configurations.
This commit is contained in:
@@ -48,7 +48,7 @@ func TestParallelModuleRefresh_CoalescesDeployApply(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
waitSucceededModuleRefreshCount(t, reg, tenant, 2)
|
||||
waitSucceededJobsByKindCount(t, reg, tenant, KindModuleRefresh, 2)
|
||||
|
||||
deployJobs, _, _ := reg.List(tenant, "", KindDeployApply, "", 100)
|
||||
if len(deployJobs) != 1 {
|
||||
@@ -75,14 +75,97 @@ func TestParallelModuleRefresh_CoalescesDeployApply(t *testing.T) {
|
||||
}
|
||||
|
||||
func waitSucceededModuleRefreshCount(t *testing.T, reg *Registry, tenant string, want int) {
|
||||
t.Helper()
|
||||
waitSucceededJobsByKindCount(t, reg, tenant, KindModuleRefresh, want)
|
||||
}
|
||||
|
||||
func waitSucceededJobsByKindCount(t *testing.T, reg *Registry, tenant, kind string, want int) {
|
||||
t.Helper()
|
||||
deadline := time.Now().Add(30 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
jobs, _, _ := reg.List(tenant, StatusSucceeded, KindModuleRefresh, "", 100)
|
||||
jobs, _, _ := reg.List(tenant, StatusSucceeded, kind, "", 100)
|
||||
if len(jobs) >= want {
|
||||
return
|
||||
}
|
||||
all, _, _ := reg.List(tenant, "", kind, "", 100)
|
||||
for _, j := range all {
|
||||
if j == nil || j.Status != StatusFailed {
|
||||
continue
|
||||
}
|
||||
snap := j.Snapshot()
|
||||
t.Fatalf("%s job failed: %#v", kind, snap["error"])
|
||||
}
|
||||
time.Sleep(5 * time.Millisecond)
|
||||
}
|
||||
t.Fatal("timeout waiting for module_refresh jobs")
|
||||
t.Fatalf("timeout waiting for %s jobs", kind)
|
||||
}
|
||||
|
||||
func TestPeerReconcile_RendersFromLatestRevisionAndQueuesDeploy(t *testing.T) {
|
||||
t.Setenv("EVOBGP_ASN_RESOLVE", "0")
|
||||
t.Setenv("EVOBGP_BIRD_ACTIVE_DIR", "") // skip bird binary path in deploy_apply
|
||||
|
||||
m := store.NewMemory()
|
||||
m.SeedDemo()
|
||||
tenant, _, modIP, _, _ := m.DemoIDs()
|
||||
for _, mod := range m.ListModules(tenant) {
|
||||
if mod == nil || mod.ID == modIP {
|
||||
continue
|
||||
}
|
||||
disabled := false
|
||||
if _, err := m.UpdateModule(tenant, mod.ID, &store.ModulePatch{Enabled: &disabled}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if _, err := m.CreateIPRangeEntry(tenant, modIP, &store.IPRangeEntry{Prefix: "10.10.0.0/24"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
peer, err := m.CreatePeer(tenant, &store.BGPPeer{
|
||||
Name: "peer-a",
|
||||
Neighbor: "192.0.2.2",
|
||||
RemoteASN: 64512,
|
||||
Enabled: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
wk := &Worker{Store: m}
|
||||
reg := NewRegistry(wk.Process)
|
||||
wk.Registry = reg
|
||||
|
||||
// Create baseline revision from enabled IP module.
|
||||
mid := modIP
|
||||
if _, _, err := reg.Enqueue(tenant, KindModuleRefresh, nil, &mid, map[string]any{"module_id": modIP}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
waitSucceededJobsByKindCount(t, reg, tenant, KindModuleRefresh, 1)
|
||||
beforeRevs, _, _ := m.ListRevisions(tenant, "", "", 200)
|
||||
|
||||
enabled := false
|
||||
if _, err := m.UpdatePeer(tenant, peer.ID, &store.PeerPatch{Enabled: &enabled}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, _, err := reg.Enqueue(tenant, KindPeerReconcile, nil, nil, map[string]any{"trigger": "peer_patch"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
waitSucceededJobsByKindCount(t, reg, tenant, KindPeerReconcile, 1)
|
||||
|
||||
afterRevs, _, _ := m.ListRevisions(tenant, "", "", 200)
|
||||
if len(afterRevs) <= len(beforeRevs) {
|
||||
t.Fatalf("expected new revision after peer_reconcile, before=%d after=%d", len(beforeRevs), len(afterRevs))
|
||||
}
|
||||
peerJobs, _, _ := reg.List(tenant, StatusSucceeded, KindPeerReconcile, "", 10)
|
||||
if len(peerJobs) == 0 {
|
||||
t.Fatal("expected succeeded peer_reconcile job")
|
||||
}
|
||||
meta := peerJobs[0].Snapshot()["meta"].(map[string]any)
|
||||
if _, ok := meta["revision_id"].(string); !ok {
|
||||
t.Fatalf("expected revision_id in peer_reconcile meta, got %#v", meta)
|
||||
}
|
||||
if title, ok := meta["job_title"].(string); !ok || title != "Обновление BGP пиров" {
|
||||
t.Fatalf("expected job_title in peer_reconcile meta, got %#v", meta["job_title"])
|
||||
}
|
||||
if _, ok := meta["deploy_apply_job_id"].(string); !ok {
|
||||
t.Fatalf("expected deploy_apply_job_id in peer_reconcile meta, got %#v", meta)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user