Skip to content

feat: add --node-condition flag and kubectl-get-like node output columns#31

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/add-node-condition-flag-support
Draft

feat: add --node-condition flag and kubectl-get-like node output columns#31
Copilot wants to merge 4 commits intomainfrom
copilot/add-node-condition-flag-support

Conversation

Copy link
Contributor

Copilot AI commented Mar 7, 2026

Adds filtering nodes by conditions (--node-condition Ready=True, --node-condition DiskPressure=False) including custom conditions from NPD, EKS Node Monitoring Agent, etc. Also makes kubectl fd nodes output match kubectl get nodes with STATUS, ROLES, and VERSION columns.

Changes

  • resource.go: NodeType GVR constant, NodeCondition struct, new field on ActionOptions, getResourceMatcher() to wire up resource-specific matchers
  • find.go: --node-condition flag with ConditionType=Status format validation, scoped to node resources only
  • columns.go: Node-specific columns — STATUS (Ready/NotReady + SchedulingDisabled), ROLES (from node-role.kubernetes.io/* labels), VERSION (kubelet)
  • nodes.go (new): NodeConditionMatcher() returns a ResourceMatcher for node condition filtering — case-insensitive, all specified conditions must match (AND)
  • universal.go: Added injectable ResourceMatcher callback type and field on UniversalHandlerOptions, keeping UniversalHandler generic — node-specific logic is fully decoupled

Design

Node condition matching uses an injectable ResourceMatcher callback pattern rather than being embedded directly in UniversalHandler. This keeps the universal handler truly universal while supporting resource-specific filters. The matcher is wired up via getResourceMatcher() in resource.go, following the same injection pattern already used for columns via GetColumnsFor().

Usage

# Find nodes that are not ready
kubectl fd nodes --node-condition Ready=False

# Find nodes with disk pressure (standard condition)
kubectl fd nodes --node-condition DiskPressure=True

# Combine with custom NPD conditions
kubectl fd nodes --node-condition Ready=True --node-condition FrequentDockerRestart=True

# Node output now shows STATUS, ROLES, VERSION like kubectl get nodes
kubectl fd nodes

🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI and others added 2 commits March 7, 2026 19:22
Co-authored-by: alikhil <7482065+alikhil@users.noreply.github.com>
Co-authored-by: alikhil <7482065+alikhil@users.noreply.github.com>
Copilot AI changed the title [WIP] Add support for --node-condition flag to filter node resources feat: add --node-condition flag and kubectl-get-like node output columns Mar 7, 2026
return true
}

if len(options.NodeConditions) > 0 {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not really align with current design of UniversalHandler, it supposed to handle all resources, however node conditions are heavily node resource related thing. Check code of pod handler, you will see that it handles special pod-only filters.

Evaluate current design, maybe it worth creating nodeHandler, or refactor everything to have only 1 handler, or other better option. Ask for approval before implementing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — node condition filtering doesn't belong in UniversalHandler. Here are the options I evaluated:

Option A: Create a dedicated NodeHandler (like PodHandler)

  • Follows the existing PodHandler pattern
  • But duplicates ~100 lines of list/delete/patch action handling for just one extra filter

Option B: Add an optional ResourceMatcher callback to UniversalHandlerOptions

  • UniversalHandler stays generic — it just calls the injected matcher alongside its own checks in resourceMatches()
  • Node-condition matching logic is passed in during handler creation in GetResourceHandler (similar to how GetColumnsFor already customizes columns per resource)
  • Zero code duplication, scales for future resource-specific filters
  • nodeConditionMatches moves out of UniversalHandler entirely

Option C: Refactor to a single handler

  • Would require merging PodHandler's typed API + exec support into the universal handler — large refactor with risk of breaking existing behavior

My recommendation is Option B — it keeps UniversalHandler truly universal, requires minimal changes, and follows the same injection pattern already used for columns. The node-specific matching function would live in a separate file (e.g. nodes.go) and be wired in via GetResourceHandler.

Which approach would you prefer?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proceed with option B

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot procee with option B

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented Option B in commit a0944b2:

  • Added ResourceMatcher callback type to UniversalHandlerOptionsUniversalHandler stays generic, just calls the injected matcher in resourceMatches()
  • Moved node condition logic to new nodes.go as NodeConditionMatcher() / nodeConditionMatches()
  • Added getResourceMatcher() in resource.go to wire up the correct matcher per resource type
  • Tests updated to use getResourceMatcher() — all pass

…sourceMatcher injection

Co-authored-by: alikhil <7482065+alikhil@users.noreply.github.com>
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.

2 participants