Files
DenozordecandCursor be3d73f374 perf: quick wins for pipeline, jobs, httpapi and web ops
- CDN snapshot: batch merge после parallel fetch, без race на persist
- ListRevisionPrefixes: лёгкая проверка revision вместо GetRevision
- Jobs: timeout/cancel context для pipeline и deploy
- HTTP server timeouts; кэш birdc для GET /peers
- ListModules: batch DoH profiles одним запросом
- Web: tab-scoped load на /operations, debounce job search, меньше over-fetch на dashboard

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 10:42:13 +07:00

98 lines
2.4 KiB
Go

package birdfmt
import (
"bytes"
"context"
"fmt"
"os/exec"
"strings"
)
// ShowProtocols runs `birdc [-s socket] show protocols all` and returns stdout (BIRD 2).
func ShowProtocols(ctx context.Context, socket, birdcBin string) (string, error) {
if birdcBin == "" {
birdcBin = "birdc"
}
args := []string{"show", "protocols", "all"}
if s := strings.TrimSpace(socket); s != "" {
args = append([]string{"-s", s}, args...)
}
cmd := exec.CommandContext(ctx, birdcBin, args...)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
msg := strings.TrimSpace(stderr.String())
if msg != "" {
return "", fmt.Errorf("birdc show protocols: %w: %s", err, msg)
}
return "", fmt.Errorf("birdc show protocols: %w", err)
}
return stdout.String(), nil
}
// CountEstablishedBGPSessions counts BGP protocol rows whose line contains "Established"
// (heuristic for `birdc show protocols` / `show protocols all` output).
func CountEstablishedBGPSessions(showProtocolsOutput string) int {
lines := strings.Split(showProtocolsOutput, "\n")
n := 0
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "name") || strings.HasPrefix(strings.ToLower(line), "table") {
continue
}
if !isBGPProtocolSummaryRow(line) {
continue
}
if strings.Contains(strings.ToLower(line), "established") {
n++
}
}
return n
}
// ParseBGPProtocolStates parses `birdc show protocols all` summary rows into protocol_name -> state.
func ParseBGPProtocolStates(output string) map[string]string {
out := make(map[string]string)
for _, raw := range strings.Split(output, "\n") {
line := strings.TrimSpace(raw)
if line == "" {
continue
}
low := strings.ToLower(line)
if strings.HasPrefix(low, "bird ") || strings.HasPrefix(low, "name ") || strings.HasPrefix(low, "table ") {
continue
}
fields := strings.Fields(line)
if len(fields) < 4 {
continue
}
if !strings.EqualFold(fields[1], "BGP") {
continue
}
state := extractBGPSessionStateLine(line)
if state == "" {
state = fields[3]
}
out[fields[0]] = state
}
return out
}
func extractBGPSessionStateLine(line string) string {
known := []string{
"Established",
"Idle",
"Connect",
"Active",
"OpenSent",
"OpenConfirm",
}
for _, st := range known {
if strings.Contains(line, st) {
return st
}
}
return ""
}