kubectl: honor --label-columns with custom-columns (#138094)

* Honor --label-columns for custom-columns output

* Validate --label-columns with custom-columns

* Remove label-columns support from custom-columns

Kubernetes-commit: 1168c4e832f0ad12b0c11b96d15e93eb3c6a8907
This commit is contained in:
Ahmad Maha 2026-04-23 06:41:36 +07:00 committed by Kubernetes Publisher
parent 7aefd5b71b
commit 76619b0639
5 changed files with 41 additions and 11 deletions

8
go.mod
View file

@ -30,10 +30,10 @@ require (
golang.org/x/sys v0.40.0
golang.org/x/text v0.33.0
gopkg.in/evanphx/json-patch.v4 v4.13.0
k8s.io/api v0.0.0-20260414141716-ddad8a9beb39
k8s.io/api v0.0.0-20260422222041-738ad2fc7666
k8s.io/apimachinery v0.0.0-20260414135623-72791e98891a
k8s.io/cli-runtime v0.0.0-20260414184533-f1c4b24e8c78
k8s.io/client-go v0.0.0-20260414143851-3c8a6967ba6d
k8s.io/cli-runtime v0.0.0-20260423030031-7c0741a165e2
k8s.io/client-go v0.0.0-20260423022421-9dcacd934a99
k8s.io/component-base v0.0.0-20260414155923-12f6271c1572
k8s.io/component-helpers v0.0.0-20260414161221-0a0fc66e1d14
k8s.io/klog/v2 v2.140.0
@ -93,3 +93,5 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
sigs.k8s.io/kustomize/api v0.21.1 // indirect
)
replace k8s.io/code-generator => k8s.io/code-generator v0.0.0-20260423023311-5e27957eb856

12
go.sum
View file

@ -191,14 +191,14 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.0.0-20260414141716-ddad8a9beb39 h1:b1Cw9zAT4gBKn8teqMMKsmQHG3Uk8oZmydz+VREwMes=
k8s.io/api v0.0.0-20260414141716-ddad8a9beb39/go.mod h1:0MHCnfE89X5hpXeB0MmNRJy2DP3MVFqj2JGtSte5YBs=
k8s.io/api v0.0.0-20260422222041-738ad2fc7666 h1:d4xRHtlzeu5W4t4BBWA7wylPf9TORY2pnILk48cjkcU=
k8s.io/api v0.0.0-20260422222041-738ad2fc7666/go.mod h1:0MHCnfE89X5hpXeB0MmNRJy2DP3MVFqj2JGtSte5YBs=
k8s.io/apimachinery v0.0.0-20260414135623-72791e98891a h1:fGTRW0wFSkwIK6xpLqCLXcZnpMVA/d/z4/VY1+V6sck=
k8s.io/apimachinery v0.0.0-20260414135623-72791e98891a/go.mod h1:Fqsi1zDY7A12KBcrFdhpzVHlFskhmS7gwXYeqzTa3zY=
k8s.io/cli-runtime v0.0.0-20260414184533-f1c4b24e8c78 h1:uTc/flpHtRbzSBKe5gigMGQYBmrcrHoKcFX2rTDnnmU=
k8s.io/cli-runtime v0.0.0-20260414184533-f1c4b24e8c78/go.mod h1:VdXZvJ/jSZjBkzCVq1lj9Lyqu+THlBEedwd0j4hMUg8=
k8s.io/client-go v0.0.0-20260414143851-3c8a6967ba6d h1:RnzbOoapqxRDsO3f1qSe7uSNlsNHs9UCu68zTXP5NBg=
k8s.io/client-go v0.0.0-20260414143851-3c8a6967ba6d/go.mod h1:1hkdN2CxttquYyEONNNKo/EZkkkgmNAg9TKv93yuDsI=
k8s.io/cli-runtime v0.0.0-20260423030031-7c0741a165e2 h1:MGVKogg4hAshw1hSCTWeXiBCJ4tFMCFMRYvcofLhIYQ=
k8s.io/cli-runtime v0.0.0-20260423030031-7c0741a165e2/go.mod h1:D5m/+ttE0nrDwgy8vHjKzgUh8AuZXS2MSnW6KuLtY7E=
k8s.io/client-go v0.0.0-20260423022421-9dcacd934a99 h1:CIF82JDCtRI1931B+/tAjKmwxikgNphE01ePM/FBtOQ=
k8s.io/client-go v0.0.0-20260423022421-9dcacd934a99/go.mod h1:kfiBH+h75s//ryif9TITxBG2rnYzMgmq6za1H8TscRs=
k8s.io/component-base v0.0.0-20260414155923-12f6271c1572 h1:WM0qw3ym5gwD/kn1QhvrxCcpJF5Jx8Ast2SHCi/2MtE=
k8s.io/component-base v0.0.0-20260414155923-12f6271c1572/go.mod h1:HROKPX7+BzMrtAugq8w74ZI2WOWqSwXpIkyn/w9N65s=
k8s.io/component-helpers v0.0.0-20260414161221-0a0fc66e1d14 h1:6Yz+oSEqY90oYkzcgaoA5xWu8Pus6d2TUtCG4sZ6YXU=

View file

@ -85,14 +85,15 @@ func (f *CustomColumnsPrintFlags) ToPrinter(templateFormat string) (printers.Res
// UniversalDecoder call must specify parameter versions; otherwise it will decode to internal versions.
decoder := scheme.Codecs.UniversalDecoder(scheme.Scheme.PrioritizedVersionsAllGroups()...)
var printer *CustomColumnsPrinter
if templateFormat == "custom-columns-file" {
file, err := os.Open(templateValue)
if err != nil {
return nil, fmt.Errorf("error reading template %s, %v\n", templateValue, err)
}
defer file.Close()
p, err := NewCustomColumnsPrinterFromTemplate(file, decoder)
return p, err
printer, err = NewCustomColumnsPrinterFromTemplate(file, decoder)
return printer, err
}
return NewCustomColumnsPrinterFromSpec(templateValue, decoder, f.NoHeaders)

View file

@ -313,6 +313,12 @@ func (o *GetOptions) Validate() error {
return fmt.Errorf("--show-labels option cannot be used with %s printer", outputOption)
}
}
if o.PrintFlags.HumanReadableFlags.ColumnLabels != nil && len(*o.PrintFlags.HumanReadableFlags.ColumnLabels) > 0 && o.PrintFlags.OutputFormat != nil {
outputOption := *o.PrintFlags.OutputFormat
if strings.HasPrefix(outputOption, "custom-columns") {
return fmt.Errorf("--label-columns option cannot be used with %s printer", outputOption)
}
}
if o.OutputWatchEvents && !(o.Watch || o.WatchOnly) {
return fmt.Errorf("--output-watch-events option can only be used with --watch or --watch-only")
}

View file

@ -133,6 +133,27 @@ func TestGetUnknownSchemaObject(t *testing.T) {
}
}
func TestGetValidateLabelColumnsWithCustomColumns(t *testing.T) {
streams, _, _, _ := genericiooptions.NewTestIOStreams()
labelColumns := []string{"app"}
outputCustom := "custom-columns=NAME:.metadata.name"
o := NewGetOptions("kubectl", streams)
o.PrintFlags.HumanReadableFlags.ColumnLabels = &labelColumns
o.PrintFlags.OutputFormat = &outputCustom
if err := o.Validate(); err == nil || !strings.Contains(err.Error(), "--label-columns option cannot be used") {
t.Fatalf("expected error for label-columns with custom-columns, got %v", err)
}
outputWide := "wide"
o = NewGetOptions("kubectl", streams)
o.PrintFlags.HumanReadableFlags.ColumnLabels = &labelColumns
o.PrintFlags.OutputFormat = &outputWide
if err := o.Validate(); err != nil {
t.Fatalf("expected no error for label-columns with wide output, got %v", err)
}
}
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func TestGetSchemaObject(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")