CRC NAD Console Plugin Deployment
Deploy the nad-console-plugin — a pre-built OpenShift Console Dynamic Plugin that sets the KUBEVIRT_DYNAMIC flag when the NetworkAttachmentDefinition CRD exists, causing the built-in networking-console-plugin to show the NAD nav item natively.
Background
The networking-console-plugin (built into OCP 4.21+) already has a full NAD UI (list, create, details) but gates it behind two flags:
NET_ATTACH_DEF— alwaystrue(hardcoded in networking-console-plugin)KUBEVIRT_DYNAMIC— normally set by the KubeVirt plugin, absent in CRC
This plugin sets KUBEVIRT_DYNAMIC=true via a console.flag/model extension (7 lines of JSON, no custom JS code) whenever the NetworkAttachmentDefinition CRD is present in the cluster.
Prerequisites
- CRC cluster is running (
crc statusshows Running) ocis logged in askubeadmin- Helm v3 is available — use
~/.local/bin/helm(v3.21.0)- Verify:
~/.local/bin/helm version
- Verify:
- The
nad-console-pluginproject is at~/app/playground/nad-console-plugin/ - Pre-built image:
quay.io/rhtevan/nad-console-plugin:latest
Step 1: Verify the NAD CRD Is Present
The plugin only activates its flag when this CRD exists. Confirm it’s in the cluster:
oc get crd network-attachment-definitions.k8s.cni.cncf.io
Expected: The CRD is present (it’s part of CRC’s default Multus CNI setup).
Step 2: Deploy with Helm
~/.local/bin/helm upgrade -i nad-console-plugin \
~/app/playground/nad-console-plugin/charts/openshift-console-plugin \
-n nad-console-plugin \
--create-namespace \
--set plugin.image=quay.io/rhtevan/nad-console-plugin:latest \
--set plugin.name=nad-console-plugin \
--set plugin.imagePullPolicy=Always
imagePullPolicy=Always ensures Kubernetes always pulls the latest image rather than using a cached version.
Step 3: Verify Pods Are Running
oc get pods -n nad-console-plugin
Expected: At least one pod in Running state serving the plugin.
# Also check the service and route/ingress
oc get svc,consoleplugin -n nad-console-plugin
Step 4: Verify the ConsolePlugin Is Registered
oc get consoleplugin nad-console-plugin
Expected output:
NAME AGE
nad-console-plugin ...
Check it is enabled in the console operator:
oc get consoles.operator.openshift.io cluster -o jsonpath='{.spec.plugins}' | tr ',' '\n'
Expected: nad-console-plugin appears in the list alongside networking-console-plugin.
Step 5: Restart the Console Pod (If Needed)
If the plugin was deployed before or the console has a stale state, force a console pod restart:
# Trigger console operator reconcile to pick up the new plugin
oc patch consoles.operator.openshift.io cluster --type=merge \
-p '{"spec":{"logLevel":"Debug"}}'
# Wait for console pods to restart
oc rollout status deployment console -n openshift-console
Then restore log level:
oc patch consoles.operator.openshift.io cluster --type=merge \
-p '{"spec":{"logLevel":"Normal"}}'
Step 6: Verify the NAD Menu Item in the Console
- Open the OpenShift Console (
crc console --url) - Log in as
kubeadmin - Hard refresh the browser (Ctrl+Shift+R) to clear any cached plugin state
- Navigate to Networking in the left sidebar
- Confirm NetworkAttachmentDefinitions appears as a menu item
Note: The NAD menu item is rendered by the built-in
networking-console-plugin, not by this plugin directly. Our plugin only sets theKUBEVIRT_DYNAMICflag that unlocks it.
Verification Checklist
oc get crd network-attachment-definitions.k8s.cni.cncf.io— CRD presentoc get pods -n nad-console-plugin— pod(s) Runningoc get consoleplugin nad-console-plugin— resource existsnad-console-pluginappears inconsoles.operator.openshift.io/clusterspec.pluginsnetworking-console-pluginalso appears in spec.plugins (required for the NAD UI)- NetworkAttachmentDefinitions menu item visible in Console → Networking
Persistence After CRC Restart
The Helm release and ConsolePlugin resource persist across CRC restarts. After a crc stop / crc start cycle, wait for the nad-console-plugin pod to reach Running state, then verify the menu item is still present.
Troubleshooting
Plugin listed but JS never loads / menu item not appearing:
The most common cause is a callback name mismatch between the SDK and the OCP console version.
The pre-built image already has the fix (loadPluginEntry patched in). If you rebuild the image,
ensure the Dockerfile includes:
sed -i 's/__load_plugin_entry__/loadPluginEntry/g' dist/plugin-entry.*.min.js
Plugin not in spec.plugins after Helm deploy:
The Helm chart’s post-install Job patches the console operator automatically. If it failed:
oc get jobs -n nad-console-plugin
oc logs job/<patcher-job-name> -n nad-console-plugin
Manually add the plugin if needed:
oc patch consoles.operator.openshift.io cluster --type=json \
-p='[{"op":"add","path":"/spec/plugins/-","value":"nad-console-plugin"}]'
Browser shows stale “failed” plugin state:
The browser caches plugin load failures. A hard refresh (Ctrl+Shift+R) is required — a normal refresh is not sufficient. Also ensure the console pod restarted after the plugin was correctly deployed.
networking-console-plugin not present:
The NAD UI is served by networking-console-plugin. Verify it is enabled:
oc get consoles.operator.openshift.io cluster -o jsonpath='{.spec.plugins}'
It should be present by default in OCP 4.21+. If missing, contact cluster admin.
Changelog
See CHANGELOG.md for version history.