Network Policy Visualizer — VS Code Extension
Visualize supported Network Policy side-by-side with YAML in VS Code using the PolicyMap component from Hubble Timescape.
Features
- Side-by-side visualization: Opens a panel next to your YAML editor showing the PolicyMap
- Live updates: The visualization updates as you edit the YAML
- Automatic detection: Recognizes supported Network Policy YAML files by
apiVersion and kind
Supported Policy Types
| Kind |
apiVersion |
supported Network PolicyNetworkPolicy |
cilium.io/v2 |
supported Network PolicyClusterwideNetworkPolicy |
cilium.io/v2 |
NetworkPolicy |
networking.k8s.io/v1 |
IsovalentNetworkPolicy |
isovalent.com/v1 |
IsovalentClusterwideNetworkPolicy |
isovalent.com/v1 |
TetragonNetworkPolicy |
cilium.io/v1alpha1 |
TetragonNetworkPolicyNamespaced |
cilium.io/v1alpha1 |
SmartSwitchNetworkPolicy |
isovalent.com/v1alpha1 |
Usage
- Open a YAML file containing a supported Network Policy
- Click the graph icon in the editor title bar, or run Network Policy: Visualize Network Policy from the command palette
- The PolicyMap visualization opens in a side panel
Timescape flows
Unlock real-time flow visibility, at the top right of the panel, opens a
short introduction to Timescape for users who have not met it yet; Unlock
then moves on to the connection form (once connected, the button reads
Timescape connected and opens the form directly). The form takes the base
URL of a Timescape public REST API plus an
optional bearer token. Once connected, the flows recorded for the workloads the policy
selects are queried from POST {base}/api/ts/v1/flows:query and listed below the
map.
The time range and refresh rate pickers in the flow panel's top bar are the ones
the main app's policy editor uses, with the same defaults: the last hour,
refreshed every 10s. A range ending at now follows the clock, and each tick
re-queries; a range between two absolute dates has nothing to advance, so the
refresh rate is not offered for it. Picking a range — or a tick advancing one —
starts a new query rather than continuing the one being paged through, so the
pages loaded so far are dropped: a page token is only valid against the window it
was issued for. A tick while a request is in flight is skipped rather than queued
behind it.
The URL is kept in globalState; the token is kept in VS Code's
SecretStorage
so it is neither written to plaintext extension state nor carried by settings
sync.
The query is issued by the extension host, not by the webview: the webview posts
a timescapeFlowsQuery message and waits for the timescapeFlowsResult carrying
the same request id (queryTimescapeFlows in src/extension.ts). The API is not
callable from a browser origin — it answers CORS preflights without an
Access-Control-Allow-Origin, which a webview fetch can only report as
Failed to fetch — whereas the host is plain Node, where no such check applies.
So the webview's CSP keeps connect-src 'none' whether or not anything is
connected, and the bearer token never leaves the host.
Running and debugging in VS Code
Open this directory as the folder — .vscode/launch.json lives here, so the
Run Extension configuration is not offered when the repository root is the
workspace folder:
code integrations/vscode-npv-extension
Press F5 and pick Run Extension. Its watch:all pre-launch task
starts the esbuild (extension host) and Vite (webview) watchers, and
--disable-extensions keeps any installed build of this extension from
interfering with the development one.
In the [Extension Development Host] window, open a YAML file whose top-level
kind: is one of the supported kinds and click the graph icon. Editing the
webview rebuilds the bundle, which the host watches and reloads automatically;
editing src/ needs Developer: Reload Window in the development window.
For the React app, use Developer: Open Webview Developer Tools — webview
console errors, failed API calls and CSP violations only appear there, not in the
extension host's debug console.
Developer: Debug Extension Host is not this. It attaches a debugger to the
extension host of the current window, running whatever is installed, so it will
not pick up local changes.
Development
Run the following from the repository root. The webview bundles source from
the main frontend/ tree, so the root dependencies must be installed first.
# Install the exact root dependencies (needed for the frontend source the webview bundles)
npm ci
# Install the extension's exact dependencies
make vscode-npv-extension-install-ci
# Build the extension (also builds the required frontend workspace packages)
make vscode-npv-extension-build
# Package as .vsix
make vscode-npv-extension-package
Run these install commands again whenever the corresponding lockfile
changes. Use npm install <package> or npm uninstall <package> from the
relevant npm project only when intentionally changing dependencies.
Other useful targets:
make vscode-npv-extension-lint # Lint src/ and webview/
make vscode-npv-extension-test # Run the unit tests
make vscode-npv-extension-format # Format with prettier
make vscode-npv-extension-format-check # Verify formatting is clean
Architecture
The extension consists of two parts:
- Extension host (
src/extension.ts) — manages the webview panel, detects YAML changes, and sends content to the webview via postMessage
- Webview app (
webview/) — a React application that renders the PolicyMap component from frontend/features/PolicyMap, built with Vite into a single JS + CSS bundle
The webview app imports the PolicyMap and its dependencies directly from the main frontend/ source tree using the ~ path alias, so it always stays in sync with the web UI.