From 3e8543177ea260e0c6349e6580c44d649a95259d Mon Sep 17 00:00:00 2001 From: Denozordec Date: Mon, 6 Apr 2026 01:22:09 +0700 Subject: [PATCH] feat: implement effective peer enabling logic during peer creation. Update CreatePeer methods in Postgres and Memory stores to utilize EffectivePeerEnabledOnCreate function, ensuring new peers are enabled by default unless specified otherwise. Add tests for effective enabling behavior. --- internal/repository/postgres.go | 3 ++- internal/store/memory_crud.go | 6 ++---- internal/store/peer_neighbor.go | 13 +++++++++++++ internal/store/peer_neighbor_test.go | 15 +++++++++++++++ web/src/routes/network/+page.svelte | 3 ++- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/internal/repository/postgres.go b/internal/repository/postgres.go index 510cd6b..302c75e 100644 --- a/internal/repository/postgres.go +++ b/internal/repository/postgres.go @@ -331,10 +331,11 @@ func (p *Postgres) CreatePeer(tenantID string, in *store.BGPPeer) (*store.BGPPee if in.SpeakerID != nil && strings.TrimSpace(*in.SpeakerID) != "" { sp = strings.TrimSpace(*in.SpeakerID) } + enabled := store.EffectivePeerEnabledOnCreate(in.Enabled, in.SessionState) _, err := p.pool.Exec(ctx, ` INSERT INTO bgp_peer (id, tenant_id, bgp_speaker_id, neighbor, remote_asn, enabled, policies_json, meta_json) VALUES ($1,$2,$3,$4::inet, $5, $6, $7::jsonb, $8::jsonb)`, - id, tenantID, sp, neighbor, in.RemoteASN, in.Enabled, pol, string(mb)) + id, tenantID, sp, neighbor, in.RemoteASN, enabled, pol, string(mb)) if err != nil { return nil, err } diff --git a/internal/store/memory_crud.go b/internal/store/memory_crud.go index 271c075..5eca7d3 100644 --- a/internal/store/memory_crud.go +++ b/internal/store/memory_crud.go @@ -629,12 +629,10 @@ func (m *Memory) CreatePeer(tenantID string, in *BGPPeer) (*BGPPeer, error) { id := uuid.NewString() p := &BGPPeer{ ID: id, TenantID: tenantID, SpeakerID: in.SpeakerID, Name: in.Name, - Neighbor: neighbor, RemoteASN: in.RemoteASN, Enabled: in.Enabled, + Neighbor: neighbor, RemoteASN: in.RemoteASN, + Enabled: EffectivePeerEnabledOnCreate(in.Enabled, in.SessionState), SessionState: in.SessionState, PoliciesJSON: in.PoliciesJSON, } - if !p.Enabled && p.SessionState == "" { - p.Enabled = true - } m.peers[id] = p return p, nil } diff --git a/internal/store/peer_neighbor.go b/internal/store/peer_neighbor.go index 039b969..eeac4bc 100644 --- a/internal/store/peer_neighbor.go +++ b/internal/store/peer_neighbor.go @@ -5,6 +5,19 @@ import ( "strings" ) +// EffectivePeerEnabledOnCreate matches API/JSON decoding: omitted "enabled" unmarshals as false in Go, +// but new peers should be enabled by default. If session_state is non-empty, false is preserved +// (agent-managed rows may be intentionally disabled). +func EffectivePeerEnabledOnCreate(inEnabled bool, sessionState string) bool { + if inEnabled { + return true + } + if strings.TrimSpace(sessionState) != "" { + return false + } + return true +} + // ParsePeerNeighbor parses a BGP neighbor value for BIRD output: a plain IPv4/IPv6 // address, or a host prefix (/32 or /128) which is a common input mistake. func ParsePeerNeighbor(s string) (netip.Addr, bool) { diff --git a/internal/store/peer_neighbor_test.go b/internal/store/peer_neighbor_test.go index d870810..2082382 100644 --- a/internal/store/peer_neighbor_test.go +++ b/internal/store/peer_neighbor_test.go @@ -2,6 +2,21 @@ package store import "testing" +func TestEffectivePeerEnabledOnCreate(t *testing.T) { + if !EffectivePeerEnabledOnCreate(false, "") { + t.Fatal("omitted enabled (false) + empty session should default to enabled") + } + if !EffectivePeerEnabledOnCreate(true, "") { + t.Fatal("explicit true") + } + if !EffectivePeerEnabledOnCreate(true, "down") { + t.Fatal("true with session") + } + if EffectivePeerEnabledOnCreate(false, "Idle") { + t.Fatal("false with non-empty session should stay disabled") + } +} + func TestParsePeerNeighbor(t *testing.T) { tests := []struct { in string diff --git a/web/src/routes/network/+page.svelte b/web/src/routes/network/+page.svelte index 1106522..3ab4bc6 100644 --- a/web/src/routes/network/+page.svelte +++ b/web/src/routes/network/+page.svelte @@ -112,7 +112,8 @@ await apiMutate(`/v1/peers/${peerEdit.id}`, 'PATCH', peerForm); toast.success('Пир обновлён'); } else { - await apiMutate('/v1/peers', 'POST', peerForm); + // API: omitted "enabled" decodes as false in Go; default new peers to enabled. + await apiMutate('/v1/peers', 'POST', { ...peerForm, enabled: true }); toast.success('Пир создан'); } peerDialog = false;