Skip to content

feat: allow resource scoped gadget embedding - #106

Open
alronova wants to merge 1 commit into
inspektor-gadget:mainfrom
alronova:fix/gadget-embed-scoping
Open

feat: allow resource scoped gadget embedding#106
alronova wants to merge 1 commit into
inspektor-gadget:mainfrom
alronova:fix/gadget-embed-scoping

Conversation

@alronova

Copy link
Copy Markdown

fix: scope embedded gadgets to specific resource (Pod/Node) only

Description

When a user embedded a gadget from a Pod or Node details page, the record stored in localStorage['headlamp_embeded_resources'] only persisted the resource kind and cluster, no specific resource identity. Every other resource of the same kind in the cluster would then display the gadget, causing visibility leaks, unintended cross-resource sharing, and destructive cross-impact on deletes.

This fix makes the embed system exclusively resource-scoped: every embedded gadget is now bound to the exact Pod or Node it was created from. There is no longer a "kind-wide" global embed mode. A new embeddedResource field (containing kind, name, namespace?, and cluster) is written at creation time and used as the single matching key on the read path. Records without embeddedResource (legacy global entries) will not match and are silently not shown.


Implementation Details

src/common/embedScoping.tsx

A self-contained helper module that is the single source of truth for all embed-scoping logic. No other file duplicates the matching logic.

  • Types: EmbeddedResourceRef, GadgetInstance
  • deriveResourceRef(jsonData, cluster): builds a normalized { kind, name, namespace?, cluster } ref from resource.jsonData
  • doesInstanceMatchResource(instance, resourceJson, cluster): requires embeddedResource to be present; matches on kind, name, cluster, and namespace (when applicable). Instances without embeddedResource return false.
  • hasEmbeddedInstancesForResource(instances, resourceJson, cluster): quick existence check used by the section gate

src/common/gadgetbackgroundinstanceform.tsx

When resource prop is a real object, the new instance now persists:

isEmbedded: true,
embeddedResource: { kind, name, namespace?, cluster }

When resource is absent (fallback path), isEmbedded is set to false and no embeddedResource is written, so it never surfaces in any embed view.

src/gadgets/gadgetDetails.tsx

Both handleRun (on-demand → headless) and deleteHeadlessGadget (headless → on-demand) rebuild a fresh localStorage record. Both now copy embeddedResource from the original so the resource binding survives mode transitions.

src/common/helpers.tsx

Preserves embeddedResource on all transitions where embedView !== 'None'. Clears it (along with kind and isEmbedded) only when detaching (embedView === 'None').

Read paths: src/index.tsx + src/gadgets/resourcegadgets.tsx

  • index.tsx gate: replaced kind-only check with hasEmbeddedInstancesForResource; also fixed a pre-existing bug where cluster was not checked at the gate level
  • resourcegadgets.tsx filter: replaced two-step kind + cluster filter with doesInstanceMatchResource, gate and renderer now use identical logic

src/common/GadgetDescription/index.tsx

The Embed Type <Select> on the standalone gadget details page is disabled whenever embeddedResource is present (i.e., always for new records), with a clear tooltip:

"This gadget is scoped to a specific resource. To change its embed type, remove it and re-add it from the target resource page."


Testing Done

Before

2026-04-12.11-37-13.mp4

After

2026-04-20.18-26-35.mp4

Now, the gadgets are being embedded and managed specific to each pod.


Checklist

Signed-off-by: alronova <aditya.divyam001@gmail.com>
@alronova

Copy link
Copy Markdown
Author

@ashu8912 @illume kindly review this PR whenever you get time.
Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: Embedded gadgets use kind-wide Pod scoping instead of Pod-specific scoping

1 participant