Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/v1alpha1/nodepool_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ type NodePoolStatus struct {
// +kubebuilder:object:root=true
// +kubebuilder:resource:scope=Cluster,shortName=np
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
// +kubebuilder:printcolumn:name="Strategy",type=string,JSONPath=`.spec.strategy`
// +kubebuilder:printcolumn:name="Providers",type=string,JSONPath=`.status.providers`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
Expand Down
11 changes: 10 additions & 1 deletion config/crd/bases/nebula.inftyai.com_nodepools.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ spec:
scope: Cluster
versions:
- additionalPrinterColumns:
- jsonPath: .status.conditions[?(@.type=="Ready")].status
name: Status
type: string
- jsonPath: .spec.strategy
name: Strategy
type: string
- jsonPath: .spec.providers[*].name
- jsonPath: .status.providers

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for this.

name: Providers
type: string
- jsonPath: .metadata.creationTimestamp
Expand Down Expand Up @@ -296,6 +299,12 @@ spec:
Placed counts existing instances per provider (booting included), for
at-a-glance balance.
type: object
providers:
description: |-
Providers is a comma-separated list of provider names from the pool
spec. kubectl printcolumns cannot join array fields via JSONPath, so
the controller materializes this summary for `kubectl get nodepool`.
type: string
type: object
type: object
served: true
Expand Down
7 changes: 7 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,12 @@ Responsibilities:
- compute `status.placed` from Bound NodeClaims per provider;
- watch NodeClaims so placement counts update as instances come and go.

The default `kubectl get nodepools` table exposes the `Ready` condition's value

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Remove this part please.

as `STATUS`, followed by strategy, providers, and age. The CRD printer column
reads the condition directly, so `status.conditions` remains the source of truth.
See the [printer-column design](design/nodepool-status-column.md) for the empty
condition and compatibility behavior.

Static spec rules are admission-time CEL validations. Examples: `Weighted`
requires a weight on every provider entry, and AWS provider entries require at
least one region.
Expand Down Expand Up @@ -502,6 +508,7 @@ spec:
failover:
blocklistTTL: 30s
status:
providers: modal,aws
placed:
modal: 2
aws: 1
Expand Down
7 changes: 6 additions & 1 deletion docs/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,12 @@ diff <(kubectl get secret nebula-webhook-server-cert -n nebula-system -o jsonpat
A pool referencing an unregistered provider shows it plainly:

```bash
kubectl get nodepool <name> -o jsonpath='{.status.conditions}'
kubectl get nodepools
# NAME STATUS STRATEGY PROVIDERS AGE
# gpu-pool False Ordered modal,aws 2m

# Inspect the condition reason and message when STATUS is False.
kubectl get nodepool <name> -o jsonpath='{.status.conditions[?(@.type=="Ready")]}'
# Ready=False / UnknownProvider means that provider's creds are missing or wrong.
```

Expand Down
46 changes: 46 additions & 0 deletions docs/design/nodepool-status-column.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# NodePool status printer column

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Remove this please, it's very straightforward.


## Context

`NodePool.status.conditions` already reports whether a pool can be used. The
controller owns a standard `Ready` condition and sets it to `True` for a valid
pool or `False` when an environment-dependent validation, such as provider
registration, fails. However, the default `kubectl get nodepools` table does not
show that signal, so operators must request the full object or write a JSONPath.

## Decision

Add a `Status` CRD printer column whose JSONPath selects the status of the
`Ready` condition:

```text
.status.conditions[?(@.type=="Ready")].status
```

The column is derived directly by the Kubernetes API server when it renders the
table. No duplicate status field or controller change is introduced. This keeps
the condition as the single source of truth and uses the standard condition
values `True`, `False`, and `Unknown`.

The column appears before policy details so pool health is visible immediately:

```text
NAME STATUS STRATEGY PROVIDERS AGE
gpu-pool True Ordered modal,runpod 2m
```

Before the controller has written the `Ready` condition, the table cell has no
value. This is preferable to manufacturing a fourth status value because absence
already means the controller has not observed the object.

## Compatibility and rollout

This is an additive change to `additionalPrinterColumns`; the stored and served
resource schema is unchanged. Existing clients that read `NodePool` objects are
unaffected. Installing the regenerated CRD is sufficient to enable the column
for existing pools, and the next `kubectl get` uses their existing conditions.

## Verification

Generation is checked into `config/crd/bases`. Regenerating the manifests keeps
the CRD printer column aligned with the marker in `nodepool_types.go`.
Loading