u/bitwisecook

New cli tool for working on config, new irule testing framework, new MCP and Claude Skills

[Tool] f5 — single-file CLI for cleaning, grepping, redacting, and round-tripping BIG-IP configs (zipapp, Python 3.10+)

Hey r/f5networks,

I've been working on a Tcl language server with deep BIG-IP support (github.com/bitwisecook/tcl-lsp) and split out a standalone CLI from it called f5. It's a single-file Python zipapp — no pip install, no venv, just drop the .pyz on your PATH. Posting in case it's useful for anyone here.

What it does

It operates on bigip.conf / SCF / UCS files (and can fetch from a live BIG-IP over iControl REST or SSH). Because it shares a parser and reference graph with the LSP, every verb sees the whole config — virtuals, pools, monitors, profiles, persistence, SNAT pools, data groups, iFiles, GTM wide-IPs, and the iRule bodies that reference them — as one connected object graph.

Verbs grouped by what you're trying to do (the standalone irule CLI from earlier releases is now folded in here as the f5 irule verb group, alongside everything else):

Live BIG-IP round-trip:

  • f5 fetch — pull SCF or UCS from a live BIG-IP device over iControl REST or SSH (ssh/scp). Credentials resolve from CLI flags, env vars, an XDG hosts.toml, or interactive prompt.
  • f5 pull — fetch a single object (virtual / pool / node / rule) from a live BIG-IP.
  • f5 push — replace or create a single object on a live BIG-IP via iControl REST.

Format conversion & file management:

  • f5 extract — convert a local UCS archive to an SCF text file.
  • f5 convert — convert between UCS / SCF / AS3 declaration formats.
  • f5 split — split an SCF into per-partition files under a directory (suitable for git).
  • f5 merge — concatenate split per-partition SCFs back into a single bigip.conf.
  • f5 tmsh — emit a tmsh create (or --modify) script that creates every object in the input config, in dependency order, ready to paste into a BIG-IP shell.

Inspection & analysis:

  • f5 stats — print object counts, partition breakdown, and top-references for a config — the "what's in this thing?" overview.
  • f5 graph — emit the object reference graph as DOT, JSON, or Mermaid.
  • f5 grep — list every BIG-IP object related to a given object path, regex, or CIDR by walking the forward-and-reverse reference graph. --cidr 10.0.0.0/8 finds objects that mention an IP in that range anywhere — header, body, or iRule text (catches class match … "10.0.0.0/8", IP::client_addr equals "10.0.0.5", etc.).
  • f5 explain — describe the resolved profile / iRule / persistence / SNAT / pool plan for a virtual or pool. "What actually happens to this thing?" in one command.
  • f5 diff — object-aware diff between two bigip.conf / SCF files; ignores property ordering and iRule whitespace.
  • f5 validate — run BIG-IP best-practice / structural checks (orphans, empty pools, monitor/cert mismatches, etc.).

Cleanup & refactoring:

  • f5 cleanup — generate a tmsh delete script for every object the config defines but no virtual server (or wide-IP) actually references, in reverse-topological order so each delete runs only after the things that point at it are gone. iRule bodies are walked too (pool …, SSL::profile …, class match …, persist …, snatpool …, node …, LSN::pool …, ifile …, HTTP::respond ifile …), with copy-propagation through set var /Common/foo; pool $var-style bindings so refs through local variables aren't missed.
  • f5 rename — rename a BIG-IP object's full path and update every reference to it across headers, bodies, and iRule scripts.

**Redaction

  • f5 redact — strip passwords, PEM blocks, and other secrets, and remap public IPs into a configurable CIDR pool while preserving CIDR relationships (a /24 of real IPs lands in a /24 of redacted IPs). Sidecar map file makes redaction reversible and stable across runs.
  • f5 unredact — reverse a previous f5 redact using its sidecar map file. Walks the map in reverse over any text, including support emails and log snippets.

PCAP & Wireshark integration:

  • f5 pcap-remap — apply an f5 redact map to a PCAP: rewrites IPv4/IPv6 src/dst, recomputes IP and TCP/UDP/ICMP checksums, and parses the F5 Ethernet trailer (legacy + DPT, tcpdump -i 0.0:nnnp) to rewrite peer IPs at schema-known offsets. Schema ported from Wireshark's packet-f5ethtrailer.c.
  • f5 enrich-pcapng — inject a Name Resolution Block (and optional TLS keylog DSB) into a .pcapng so Wireshark resolves BIG-IP names natively and decrypts TLS sessions inline.
  • f5 enrich-wireshark — generate a Wireshark profile directory (hosts / subnets / vlans / column layouts / coloring rules) tailored to a specific BIG-IP config.
  • f5 explain-flow — for every unique flow in a PCAP, find the matching virtual server and print the per-flow plan: profiles in attach order, LTM policies, APM access profile, expected iRule event firing sequence, the verbatim when EVENT { … } body for each event, persistence, SNAT, default pool & members, and any GTM wide-IPs. Optional --tshark / --keylog for richer L7 + TLS decoding; --simulate runs each matched session under the test orchestrator.

iRules-specific (the old standalone irule CLI is now this verb group):

  • f5 irule event-order — show the iRules events used in a file in canonical firing order.
  • f5 irule event-info — look up iRules event metadata and the commands that are valid in that event.
  • f5 irule lint — run iRule-only lint rules over a bigip.conf / SCF. Backed by a shared lint registry (irule-deprecated-command, irule-empty-when-block, irule-unknown-event, irule-missing-object, …) that's also used by f5 validate, so what lint flags is a strict subset of validate.
  • f5 irule trace — static event-flow trace from a starting event — see which events fire next, and which iRule bodies they activate.
  • f5 irule extract — write each iRule body to a standalone .tcl file.
  • f5 irule format (alias fmt) — pretty-print iRule source with canonical indentation and spacing. Accepts .irul / .irule / .tcl files, bigip.conf / SCF / UCS, --source snippets, or stdin. Single rule → stdout (or -o FILE); multiple rules → -o DIR for one file per rule.
  • f5 irule minify (alias min) — strip comments, collapse whitespace, join commands with semicolons. --compact rewrites var/proc names to short identifiers, --symbol-map FILE writes the original→compacted mapping, --aggressive runs every optimiser pass then minifies, --isolated also compacts globals for self-contained scripts.
  • f5 irule context — bundle each iRule with the BIG-IP objects it references (pools, data groups, persistence profiles, SNAT pools, profiles, monitors, nodes, called rules) plus a one-hop transitive expansion (pool members → nodes; pool monitor → monitor). Designed to be dropped into an LLM prompt. Output as JSON or as a Tcl-flavoured text block; --rule /Common/foo (repeatable) limits output to specific rules.

Shell integration:

  • f5 completion — print a bash / fish / zsh completion script for the f5 CLI (verb names, every flag, *.conf / *.scf paths).

iRule test framework + Event Orchestrator

Bundled in is an iRule Event Orchestrator — a deterministic test harness that runs in plain tclsh, no BIG-IP required. It simulates the BIG-IP event lifecycle, pool selection, data groups, session/persist tables, SNAT, profiles, and multi-TMM CMP behaviour, so you can finally write proper unit tests for iRules and run them in CI.

Minimal example:

::orch::configure_tests \
    -profiles {TCP HTTP} \
    -irule { when HTTP_REQUEST { pool web_pool } } \
    -setup { ::orch::add_pool web_pool {{10.0.0.1:80}} }

::orch::test "routing-1.0" "basic request goes to web_pool" -body {
    ::orch::run_http_request -host "example.com" -uri "/"
    ::orch::assert_that pool_selected equals "web_pool"
}

exit [::orch::done]

Highlights:

  • Canonical event firing order driven by configured profiles (TCP / SSL / HTTP / WebSocket / SIP / DNS).
  • Stub commands for pool, node, snat, persist, table, class match, HTTP::*, SSL::*, IP::*, LB::*, session, STATS::*, log, after, clock, … with introspectable side-effects.
  • Readable assertions (pool_selected, node_selected, http_respond_status, log_lines, table_get, persist_lookup, …).
  • Multi-TMM / CMP simulation with a fake CMP distribution function — catches the classic "works on TMM 0 but breaks under CMP spread" bugs (static:: writes in hot events, races on table shared state).
  • Auto-generate tests from an iRule's CFG with generate-test (CLI), the generate_irule_test MCP tool, or the "Generate iRule Test" command in VS Code / JetBrains / Sublime / Zed.
  • Runs in plain tclsh 8.4 / 8.5 / 8.6 / 9.0 → trivial to wire into GitHub Actions / GitLab / Jenkins.

Generate and run:

uv run python -m ai.claude.tcl_ai generate-test path/to/my.irule
tclsh path/to/my.irule.test.tcl

Companion MCP tool + Claude Code skills

The cleanup and PCAP-vs-config pipelines are also reachable from AI tooling, so f5, the MCP server, and the skill pack drive the same Python underneath:

  • New MCP tool — explain_flow — added to the existing tcl-lsp-mcp-server.pyz MCP server. Same compute path as f5 explain-flow, exposed as a typed tool to any MCP-compatible client (Claude Desktop, Cursor, Continue, custom agents).
  • New MCP tool — irule_with_context — same compute path as f5 irule context. What an agent should call before reasoning about an iRule end-to-end: the returned bundle carries the rule body plus every referenced BIG-IP object's source (pools, data groups, persistence, SNAT pools, profiles, monitors, nodes, called rules) with optional transitive expansion, so the agent doesn't have to hand-walk the config or be force-fed an entire bigip.conf.
  • New Claude Code skill — bigip-cleanup — drives the same reference-graph walker behind f5 cleanup. Ask Claude "find the orphaned objects in this bigip.conf and write me the delete script" and it runs the full pipeline (cleanup report + ordered tmsh delete script + summary).
  • New Claude Code skill — explain-flow — drives the same code as f5 explain-flow and the explain_flow MCP tool, with a structured narration prompt so the model walks the per-flow plan field by field. Ask "explain this PCAP against the attached config" and you get the matched VIP, profile chain, iRule events that fired, observed pool member, termination cause, and (with --simulate) the actual orchestrator outcome.

Both skills ship in the tcl-lsp-claude-skills-<version>.zip bundle. Install user-level or project-scoped:

unzip tcl-lsp-claude-skills-<version>.zip -d ~/.claude/skills/
# or, project-scoped:
unzip tcl-lsp-claude-skills-<version>.zip -d ./.claude/skills/

Wire the MCP server into Claude Desktop with one entry in claude_desktop_config.json:

{
  "mcpServers": {
    "tcl-lsp": {
      "command": "/path/to/tcl-lsp-mcp-server.pyz"
    }
  }
}

The Python is shared all the way down, so a fix or feature added to an f5 verb is immediately picked up by the MCP tool and the skill — no parallel implementations to drift apart.

Install (as a .pyz)

Minimum requirements: Python 3.10+. That's literally it — no pip, no venv, no compile step.

mkdir -p ~/.local/bin
curl -L -o ~/.local/bin/f5 \
  https://github.com/bitwisecook/tcl-lsp/releases/latest/download/f5-<version>.pyz
chmod +x ~/.local/bin/f5

f5 --help

System-wide is the same file in /usr/local/bin/f5. If you don't trust the shebang, invoke it explicitly: python3 ~/.local/bin/f5 cleanup ….

Optional dependencies

Everything below is opt-in. f5 works without any of them; verbs that use one degrade gracefully when it isn't on PATH.

  • tshark (Wireshark CLI) — for f5 explain-flow --tshark and --keylog. Adds HTTP method/Host/URI, TLS SNI/version/cipher/ALPN, TLS alerts, F5 reset cause. With --keylog FILE (NSS-format SSLKEYLOGFILE), HTTPS payloads decrypt so HTTP decoding works on TLS-wrapped sessions. Without tshark, the built-in libpcap+pcapng walker still handles common TLS ClientHello / HTTP request prefixes.
  • tclsh — for f5 explain-flow --simulate and for running the generated iRule Event Orchestrator test files. --simulate replays each matched session's iRule with the captured HTTP/TLS state and reports actual pool/node selection, HTTP::respond decisions, log lines, and side-effects (one tclsh subprocess per session). The test framework itself is pure Tcl and runs on tclsh 8.4 / 8.5 / 8.6 / 9.0.
  • ssh / scp — for f5 fetch / pull / push over SSH (the alternative to iControl REST for live BIG-IP round-trip).

Shell completion

f5 completion bash > ~/.local/share/bash-completion/completions/f5
f5 completion fish > ~/.config/fish/completions/f5.fish
f5 completion zsh  > "${ZDOTDIR:-$HOME}/.zsh/completions/_f5"

Covers verb names, every flag, and *.conf / *.scf positional paths. --hint prints install instructions alongside the script.

Quick try

f5 cleanup samples/bigip/bigip.conf
f5 grep --cidr 10.0.0.0/8 bigip.conf
f5 explain virtual /Common/my_vs bigip.conf
f5 diff old.scf new.scf
f5 explain-flow capture.pcap bigip.conf --tshark

Repo + releases: https://github.com/bitwisecook/tcl-lsp

Coming next: I'm putting together a web UI for this — drop in a bigip.conf (or point it at a live device) in a browser and get the cleanup report, reference graph, explain virtual view, redact/unredact round-trip, explain-flow PCAP-vs-config trace, and the iRule test orchestrator with results, logs, and pool selection shown next to the iRule source. Same engine underneath, no install beyond a browser. Will post here when it's ready for testers — watch the repo if you want a heads-up.

Happy to take feature requests, bug reports, and "I wish there was a verb that did X" suggestions — especially from anyone with a "we keep meaning to clean this config up" backlog. Cheers.

reddit.com
u/bitwisecook — 4 days ago