Skip to content

Commit 3cd50ed

Browse files
committed
Initial open-source release of NetOpsBench
0 parents  commit 3cd50ed

311 files changed

Lines changed: 40908 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
---
2+
name: netopsbench-diagnosis-playbook
3+
description: Use this skill when diagnosing NetOpsBench DCN benchmark faults with Pingmesh, topology, routing, interface, and log evidence. It helps localize a single infrastructure device or interface, avoid timeout-prone tool loops, and normalize conclusions to benchmark-friendly fault labels such as link_down, packet_loss, high_latency, packet_corruption, mtu_mismatch, blackhole_route, and static_route_misconfig.
4+
compatibility: Requires the NetOpsBench MCP toolset with Pingmesh, topology, BGP, route, interface, log, ping, and traceroute tools.
5+
allowed-tools: get_pingmesh_summary get_pingmesh_hotspots get_topology get_all_bgp_status get_bgp_neighbors get_route_table get_device_interfaces get_interface_metrics get_device_logs get_device_config get_bgp_rib ping_test traceroute
6+
---
7+
8+
# NetOpsBench Diagnosis Playbook
9+
10+
## When to use
11+
12+
Use this skill for NetOpsBench troubleshooting tasks where you must produce a benchmark-friendly diagnosis from live MCP tool evidence.
13+
14+
Use it especially when one of these risks appears:
15+
16+
- Pingmesh anomalies are broad and you need to reduce the search space quickly
17+
- Pingmesh shows zero anomalies, but the network may still have a routing or forwarding fault
18+
- Pingmesh reports `mtu_or_fragmentation_suspect` but ordinary small-packet checks still look healthy
19+
- The evidence points to a path between multiple leaves and you must choose a single owner or stay inconclusive
20+
- You have enough evidence for a fault, but your current fault label is free-form instead of a benchmark label
21+
- You are about to return multiple devices or a wide interface set
22+
23+
## Core goals
24+
25+
1. Prefer one infrastructure device owner over a path-level multi-device answer.
26+
2. Prefer one interface only when evidence is strong; otherwise omit the interface.
27+
3. Use benchmark fault labels, not descriptive prose, for `fault_type`.
28+
4. Keep tool exploration narrow to avoid 300s/600s dead-ends.
29+
30+
## Fast triage
31+
32+
Always begin with exactly these three tools unless the user already gave equivalent outputs:
33+
34+
1. `get_pingmesh_summary`
35+
2. `get_pingmesh_hotspots`
36+
3. `get_topology`
37+
38+
Classify the case into one of these modes before doing anything else:
39+
40+
- `latency-dominant`: latency spikes are present and packet loss is absent or minor
41+
- `loss-dominant`: packet loss events are present
42+
- `zero-anomaly`: total Pingmesh anomalies are zero
43+
44+
After triage, choose at most two candidate devices for deeper validation.
45+
46+
If Pingmesh explicitly reports `mtu_or_fragmentation_suspect`, treat that as a special branch even when packet loss is zero and latency is mild.
47+
48+
## Candidate-device rules
49+
50+
Use these tie-breakers in order:
51+
52+
1. Pick the leaf or spine that appears most often in Pingmesh hotspots.
53+
2. Prefer a single leaf over a leaf pair when one side has stronger local evidence.
54+
3. Prefer infrastructure devices over clients unless a client-only fault is explicit.
55+
4. If evidence is only path-level and no owner emerges, return `inconclusive` instead of listing multiple devices.
56+
57+
Never return comma-separated or "A and B" device locations unless the user explicitly asks for a path summary rather than a benchmark answer.
58+
59+
## Evidence collection by mode
60+
61+
### A. Latency-dominant
62+
63+
Use this order:
64+
65+
1. `get_device_interfaces` on the top candidate leaf
66+
2. `get_interface_metrics` on the top 2-3 interfaces most likely to carry the affected traffic
67+
3. `get_all_bgp_status` or targeted `get_bgp_neighbors`
68+
4. `get_device_logs`
69+
5. `get_route_table` only if routing inconsistency is still plausible
70+
71+
Interpretation:
72+
73+
- Healthy BGP plus localized latency spikes usually means `high_latency`, not a routing fault.
74+
- If one leaf clearly owns the hotspots and its network-facing ports show pressure, return that leaf.
75+
- If the device is clear but the exact interface is not, omit the interface instead of naming many ports.
76+
77+
### B. Loss-dominant
78+
79+
Use this order:
80+
81+
1. `get_device_interfaces` on the top candidate leaf
82+
2. `get_interface_metrics` on likely path interfaces
83+
3. `get_all_bgp_status` or targeted `get_bgp_neighbors`
84+
4. `get_device_logs`
85+
5. `ping_test` or `traceroute` only for one or two decisive directed checks
86+
6. `get_route_table` only if routing evidence is needed to distinguish route faults from data-plane faults
87+
88+
Interpretation:
89+
90+
- Healthy BGP plus localized loss usually points to `packet_loss`, `link_down`, `packet_corruption`, or `mtu_mismatch`.
91+
- If a specific interface is down or clearly degraded, prefer `link_down`.
92+
- If connectivity still exists but loss is the dominant symptom, prefer `packet_loss`.
93+
- If the evidence suggests integrity or fragmentation behavior rather than simple drops, consider `packet_corruption` or `mtu_mismatch`, but only if route absence is not the better explanation.
94+
95+
### D. MTU / fragmentation-special branch
96+
97+
Use this branch whenever Pingmesh reports `mtu_or_fragmentation_suspect`, even if ordinary client-to-client ping still succeeds.
98+
99+
Use this order:
100+
101+
1. `ping_test` from an affected client with default small packets
102+
3. `ping_test` from the same client to the same destination with `payload_size=1472` and `dont_fragment=true`
103+
4. If needed, repeat `ping_test` with a larger DF probe such as `payload_size=2000`
104+
5. `get_device_interfaces` on the two most likely devices on the affected path
105+
6. `get_interface_metrics` on the most relevant path interfaces
106+
7. `get_all_bgp_status` or targeted `get_bgp_neighbors`
107+
8. `get_route_table` only if route absence is still plausible
108+
109+
Interpretation:
110+
111+
- Small-packet success does not clear `mtu_mismatch`.
112+
- The strongest directed symptom is: small client ping succeeds, but large DF ping fails.
113+
- If large DF probes fail only on paths that cross one spine or one leaf uplink, rank that device/interface higher.
114+
- If both small and large DF probes succeed, downgrade `mtu_mismatch` confidence and keep looking for another explanation.
115+
- If BGP and routing are healthy and large DF probes fail selectively, prefer `mtu_mismatch` over route faults.
116+
117+
### C. Zero-anomaly
118+
119+
This is the highest-priority timeout trap. Do not keep repeating Pingmesh queries.
120+
121+
Switch immediately to this route-centric sequence:
122+
123+
1. `get_route_table` on the suspected owner and one nearby peer device
124+
2. `ping_test` for one targeted failing destination only when a client-side directed check is needed
125+
3. `traceroute` for one targeted path if needed
126+
4. `get_all_bgp_status` or targeted `get_bgp_neighbors`
127+
5. `get_device_config` to inspect running configuration for route or BGP misconfigurations
128+
6. `get_device_interfaces`
129+
7. `get_device_logs`
130+
131+
Interpretation:
132+
133+
- Zero Pingmesh anomalies does not mean healthy routing.
134+
- If route-table evidence points to a wrong or missing static route on one device, prefer `static_route_misconfig`.
135+
- If traffic is dropped due to forwarding behavior but the exact static misconfiguration is not proven, prefer `blackhole_route`.
136+
- Do not fall back to generic congestion explanations when Pingmesh is clean.
137+
138+
## Interface ranking
139+
140+
Only return an interface if you can rank one interface above the others with specific evidence.
141+
142+
Rank interfaces using this order:
143+
144+
1. Topology relevance: is the interface actually on the affected path?
145+
2. Hard state: oper-down, admin-down, or clearly abnormal counters
146+
3. Directionality: does hotspot direction or traceroute implicate this side?
147+
4. Consistency: do logs and interface metrics agree?
148+
149+
If you cannot produce one top interface, leave `location.interface` empty.
150+
151+
Never return a long interface bundle such as `Ethernet0/Ethernet4/Ethernet8/...` in the final benchmark answer.
152+
153+
## Fault label normalization
154+
155+
Use only these benchmark labels in `fault_type`:
156+
157+
- `link_down`
158+
- `packet_loss`
159+
- `high_latency`
160+
- `packet_corruption`
161+
- `mtu_mismatch`
162+
- `blackhole_route`
163+
- `static_route_misconfig`
164+
165+
Map evidence to labels like this:
166+
167+
- `high_latency`: latency spikes dominate, reachability mostly remains, control plane is healthy
168+
- `packet_loss`: drop symptoms dominate, reachability still exists, no stronger route-fault evidence
169+
- `link_down`: one specific link or interface is down or strongly isolated as failed
170+
- `packet_corruption`: integrity-like or corruption-like path degradation is better supported than simple loss
171+
- `mtu_mismatch`: fragmentation/selective path failure is more plausible than route absence or link-down
172+
- `blackhole_route`: forwarding to a destination disappears due to a route/next-hop blackhole, but static-route proof is incomplete
173+
- `static_route_misconfig`: route-table evidence points to a wrong or missing static route on a specific device
174+
175+
If you are currently thinking in a free-form label like "leaf-side congestion on fabric uplinks", convert it to the closest benchmark label before returning.
176+
177+
## Stop conditions
178+
179+
Do not keep exploring once you have:
180+
181+
- one clear device owner and enough evidence for a benchmark label, or
182+
- no owner after checking two devices and at most three interfaces per device
183+
184+
If you hit the second condition, return `inconclusive` with concise evidence instead of opening more branches.
185+
186+
## Final answer checklist
187+
188+
Before returning, verify all of these:
189+
190+
- `verdict` is not `network_healthy` when Pingmesh anomalies exist or directed checks fail
191+
- `fault_type` is one of the seven benchmark labels above
192+
- `location.device` is a single device string when you have a justified owner
193+
- `location.interface` is either one interface or empty
194+
- `evidence` cites concrete tool findings, not speculation
195+
196+
## Failure modes to avoid
197+
198+
- Re-running Pingmesh tools after a `zero-anomaly` classification
199+
- Treating ordinary small-packet ping success as proof that `mtu_mismatch` is absent
200+
- Using leaf/spine-originated `ping_test` or `traceroute` as decisive evidence; prefer client-source checks
201+
- Returning multiple devices because the path looks symmetric
202+
- Returning huge interface sets instead of a ranked top choice
203+
- Using descriptive prose as `fault_type`
204+
- Spending the budget on broad scans before checking routing in zero-anomaly cases

.editorconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
trim_trailing_whitespace = true
8+
indent_style = space
9+
indent_size = 4
10+
11+
[*.{yml,yaml,json,md,toml}]
12+
indent_size = 2
13+
14+
[Makefile]
15+
indent_style = tab
16+
17+
[*.{sh,bash}]
18+
indent_size = 2

.env.example

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# =============================================================================
2+
# NetOpsBench Environment Configuration
3+
# Copy this file to .env and update the values for your environment.
4+
# Do not commit .env to git.
5+
# =============================================================================
6+
7+
# --- LLM API Keys (for benchmark agents) ---
8+
MINIMAX_API_KEY=your-minimax-api-key
9+
OPENAI_API_KEY=your-openai-compatible-api-key
10+
# ZHIPU_API_KEY=your-zhipu-api-key
11+
# DEEPSEEK_API_KEY=your-deepseek-api-key
12+
# KIMI_API_KEY=your-kimi-api-key
13+
# OPENAI_BASE_URL=https://api.openai.com/v1
14+
15+
# --- LangSmith Tracing (optional) ---
16+
LANGSMITH_API_KEY=your-langsmith-api-key
17+
LANGSMITH_TRACING=true
18+
LANGSMITH_PROJECT=NetOpsBench
19+
20+
# --- InfluxDB ---
21+
NETOPSBENCH_INFLUXDB_URL=http://localhost:8086
22+
NETOPSBENCH_INFLUXDB_TOKEN=replace-me # REQUIRED: set a real token before deployment
23+
NETOPSBENCH_INFLUXDB_ORG=netopsbench
24+
NETOPSBENCH_INFLUXDB_BUCKET=netopsbench
25+
26+
# --- Grafana ---
27+
# NETOPSBENCH_GRAFANA_URL=http://localhost:3000
28+
# NETOPSBENCH_GRAFANA_PASSWORD=admin
29+
# NETOPSBENCH_GRAFANA_INFLUXDB_URL=http://influxdb:8086
30+
# NETOPSBENCH_GRAFANA_DEFAULT_BUCKET=netopsbench
31+
32+
# --- Topology ---
33+
# NETOPSBENCH_TOPOLOGY_DIR=lab-topology/generated_topology_xs
34+
# NETOPSBENCH_TOPOLOGY_ID=dcn
35+
# NETOPSBENCH_LAB_NAME=dcn
36+
# NETOPSBENCH_MGMT_SUBNET= # Override management subnet (e.g. 172.20.20.0/24)
37+
# NETOPSBENCH_MGMT_NETWORK= # Override Docker management network name
38+
39+
# --- SONiC / gNMI Telemetry ---
40+
# SONIC_GNMI_PORT=50051
41+
# SONIC_GNMI_USERNAME=admin
42+
# SONIC_GNMI_PASSWORD= # Set the SONiC gNMI password for telemetry collection
43+
# SONIC_GNMI_ENCODING=json_ietf
44+
# SONIC_GNMI_TARGET=COUNTERS_DB
45+
# SONIC_GNMI_SUBSCRIPTION_MODE=on_change # on_change | sample | target_defined
46+
# SONIC_GNMI_SAMPLE_INTERVAL=10s # Only used when subscription_mode=sample
47+
48+
# --- Telemetry collectors (sFlow / syslog) ---
49+
# NETOPSBENCH_SFLOW_COLLECTOR= # sFlow collector IP (defaults to management IP)
50+
# NETOPSBENCH_SYSLOG_COLLECTOR= # Syslog collector IP (defaults to management IP)
51+
# NETOPSBENCH_SFLOW_PORT=6343
52+
# NETOPSBENCH_SFLOW_POLLING_INTERVAL=20
53+
# NETOPSBENCH_SFLOW_SAMPLE_RATE=1000
54+
# NETOPSBENCH_SFLOW_SAMPLE_DIRECTION=ingress
55+
56+
# --- Pingmesh ---
57+
# PINGMESH_CYCLE_INTERVAL=5 # Probe cycle interval in seconds
58+
59+
# --- Runtime / debug ---
60+
# NETOPSBENCH_LOG_LEVEL=INFO # DEBUG | INFO | WARNING | ERROR
61+
# NETOPSBENCH_NO_SUDO=0 # Set to 1 in CI/test environments without sudo
62+
63+
# --- Worker Pool ---
64+
# NETOPSBENCH_WORKER_DEPLOY_JOBS= # Parallel worker deploy jobs (default: num_workers)
65+
# NETOPSBENCH_SONIC_WAIT_TRIES=180 # Max SONiC readiness retries (5s each, default: 15 min)
66+
# NETOPSBENCH_AGENT_TIMEOUT_SECONDS=300
67+
# NETOPSBENCH_WORKER_AGENT_TIMEOUT_SECONDS=600
68+
# NETOPSBENCH_WORKER_DISABLE_LANGSMITH=false

.github/workflows/docs-pages.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: docs-pages
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
pages: write
12+
id-token: write
13+
14+
concurrency:
15+
group: docs-pages
16+
cancel-in-progress: true
17+
18+
jobs:
19+
build:
20+
runs-on: ubuntu-latest
21+
env:
22+
NEXT_PUBLIC_BASE_PATH: /${{ github.event.repository.name }}
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
27+
- name: Setup Node
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: '20'
31+
cache: npm
32+
cache-dependency-path: docs/package-lock.json
33+
34+
- name: Configure Pages
35+
uses: actions/configure-pages@v5
36+
with:
37+
enablement: true
38+
39+
- name: Install docs dependencies
40+
working-directory: docs
41+
run: npm ci
42+
43+
- name: Build docs site
44+
working-directory: docs
45+
run: npm run build
46+
47+
- name: Upload Pages artifact
48+
uses: actions/upload-pages-artifact@v3
49+
with:
50+
path: docs/out
51+
52+
deploy:
53+
needs: build
54+
runs-on: ubuntu-latest
55+
environment:
56+
name: github-pages
57+
url: ${{ steps.deployment.outputs.page_url }}
58+
steps:
59+
- name: Deploy to GitHub Pages
60+
id: deployment
61+
uses: actions/deploy-pages@v4

0 commit comments

Comments
 (0)