mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +00:00
Fix error printing objects from kubectl get -w
This commit is contained in:
parent
35c2e70dd1
commit
31b3e01f1e
@ -1160,6 +1160,19 @@ run_kubectl_get_tests() {
|
|||||||
output_message=$(! kubectl get pod valid-pod --allow-missing-template-keys=false -o go-template='{{.missing}}' "${kube_flags[@]}")
|
output_message=$(! kubectl get pod valid-pod --allow-missing-template-keys=false -o go-template='{{.missing}}' "${kube_flags[@]}")
|
||||||
kube::test::if_has_string "${output_message}" 'map has no entry for key "missing"'
|
kube::test::if_has_string "${output_message}" 'map has no entry for key "missing"'
|
||||||
|
|
||||||
|
### Test kubectl get watch
|
||||||
|
output_message=$(kubectl get pods -w --request-timeout=1 "${kube_flags[@]}")
|
||||||
|
kube::test::if_has_string "${output_message}" 'STATUS' # headers
|
||||||
|
kube::test::if_has_string "${output_message}" 'valid-pod' # pod details
|
||||||
|
output_message=$(kubectl get pods/valid-pod -o name -w --request-timeout=1 "${kube_flags[@]}")
|
||||||
|
kube::test::if_has_not_string "${output_message}" 'STATUS' # no headers
|
||||||
|
kube::test::if_has_string "${output_message}" 'pods/valid-pod' # resource name
|
||||||
|
output_message=$(kubectl get pods/valid-pod -o yaml -w --request-timeout=1 "${kube_flags[@]}")
|
||||||
|
kube::test::if_has_not_string "${output_message}" 'STATUS' # no headers
|
||||||
|
kube::test::if_has_string "${output_message}" 'name: valid-pod' # yaml
|
||||||
|
output_message=$(! kubectl get pods/invalid-pod -w --request-timeout=1 "${kube_flags[@]}" 2>&1)
|
||||||
|
kube::test::if_has_string "${output_message}" '"invalid-pod" not found'
|
||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
kubectl delete pods valid-pod "${kube_flags[@]}"
|
kubectl delete pods valid-pod "${kube_flags[@]}"
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ func stringBody(body string) io.ReadCloser {
|
|||||||
|
|
||||||
func Example_printReplicationControllerWithNamespace() {
|
func Example_printReplicationControllerWithNamespace() {
|
||||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
WithNamespace: true,
|
WithNamespace: true,
|
||||||
ColumnLabels: []string{},
|
ColumnLabels: []string{},
|
||||||
})
|
})
|
||||||
@ -200,7 +200,7 @@ func Example_printReplicationControllerWithNamespace() {
|
|||||||
|
|
||||||
func Example_printMultiContainersReplicationControllerWithWide() {
|
func Example_printMultiContainersReplicationControllerWithWide() {
|
||||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
Wide: true,
|
Wide: true,
|
||||||
ColumnLabels: []string{},
|
ColumnLabels: []string{},
|
||||||
})
|
})
|
||||||
@ -255,7 +255,7 @@ func Example_printMultiContainersReplicationControllerWithWide() {
|
|||||||
|
|
||||||
func Example_printReplicationController() {
|
func Example_printReplicationController() {
|
||||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
ColumnLabels: []string{},
|
ColumnLabels: []string{},
|
||||||
})
|
})
|
||||||
printersinternal.AddHandlers(p)
|
printersinternal.AddHandlers(p)
|
||||||
@ -309,7 +309,7 @@ func Example_printReplicationController() {
|
|||||||
|
|
||||||
func Example_printPodWithWideFormat() {
|
func Example_printPodWithWideFormat() {
|
||||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
Wide: true,
|
Wide: true,
|
||||||
ColumnLabels: []string{},
|
ColumnLabels: []string{},
|
||||||
})
|
})
|
||||||
@ -352,7 +352,7 @@ func Example_printPodWithWideFormat() {
|
|||||||
|
|
||||||
func Example_printPodWithShowLabels() {
|
func Example_printPodWithShowLabels() {
|
||||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
ShowLabels: true,
|
ShowLabels: true,
|
||||||
ColumnLabels: []string{},
|
ColumnLabels: []string{},
|
||||||
})
|
})
|
||||||
@ -490,7 +490,7 @@ func newAllPhasePodList() *api.PodList {
|
|||||||
|
|
||||||
func Example_printPodHideTerminated() {
|
func Example_printPodHideTerminated() {
|
||||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
ColumnLabels: []string{},
|
ColumnLabels: []string{},
|
||||||
})
|
})
|
||||||
printersinternal.AddHandlers(p)
|
printersinternal.AddHandlers(p)
|
||||||
@ -525,7 +525,7 @@ func Example_printPodHideTerminated() {
|
|||||||
|
|
||||||
func Example_printPodShowAll() {
|
func Example_printPodShowAll() {
|
||||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
ShowAll: true,
|
ShowAll: true,
|
||||||
ColumnLabels: []string{},
|
ColumnLabels: []string{},
|
||||||
})
|
})
|
||||||
@ -554,7 +554,7 @@ func Example_printPodShowAll() {
|
|||||||
|
|
||||||
func Example_printServiceWithNamespacesAndLabels() {
|
func Example_printServiceWithNamespacesAndLabels() {
|
||||||
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
f, tf, _, ns := cmdtesting.NewAPIFactory()
|
||||||
p := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
p := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
WithNamespace: true,
|
WithNamespace: true,
|
||||||
ColumnLabels: []string{"l1"},
|
ColumnLabels: []string{"l1"},
|
||||||
})
|
})
|
||||||
|
@ -253,8 +253,16 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [
|
|||||||
// print the current object
|
// print the current object
|
||||||
filteredResourceCount := 0
|
filteredResourceCount := 0
|
||||||
if !isWatchOnly {
|
if !isWatchOnly {
|
||||||
if err := printer.PrintObj(obj, out); err != nil {
|
var objsToPrint []runtime.Object
|
||||||
return fmt.Errorf("unable to output the provided object: %v", err)
|
if isList {
|
||||||
|
objsToPrint, _ = meta.ExtractList(obj)
|
||||||
|
} else {
|
||||||
|
objsToPrint = append(objsToPrint, obj)
|
||||||
|
}
|
||||||
|
for _, objToPrint := range objsToPrint {
|
||||||
|
if err := printer.PrintObj(objToPrint, out); err != nil {
|
||||||
|
return fmt.Errorf("unable to output the provided object: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
filteredResourceCount++
|
filteredResourceCount++
|
||||||
cmdutil.PrintFilterCount(filteredResourceCount, mapping.Resource, filterOpts)
|
cmdutil.PrintFilterCount(filteredResourceCount, mapping.Resource, filterOpts)
|
||||||
|
@ -794,7 +794,7 @@ func TestWatchSelector(t *testing.T) {
|
|||||||
cmd.Flags().Set("selector", "a=b")
|
cmd.Flags().Set("selector", "a=b")
|
||||||
cmd.Run(cmd, []string{"pods"})
|
cmd.Run(cmd, []string{"pods"})
|
||||||
|
|
||||||
expected := []runtime.Object{podList, events[2].Object, events[3].Object}
|
expected := []runtime.Object{&pods[0], &pods[1], events[2].Object, events[3].Object}
|
||||||
verifyObjects(t, expected, tf.Printer.(*testPrinter).Objects)
|
verifyObjects(t, expected, tf.Printer.(*testPrinter).Objects)
|
||||||
|
|
||||||
if len(buf.String()) == 0 {
|
if len(buf.String()) == 0 {
|
||||||
|
@ -416,7 +416,7 @@ func (f *ring0Factory) SuggestedPodTemplateResources() []schema.GroupResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *ring0Factory) Printer(mapping *meta.RESTMapping, options printers.PrintOptions) (printers.ResourcePrinter, error) {
|
func (f *ring0Factory) Printer(mapping *meta.RESTMapping, options printers.PrintOptions) (printers.ResourcePrinter, error) {
|
||||||
p := printers.NewHumanReadablePrinter(options)
|
p := printers.NewHumanReadablePrinter(f.JSONEncoder(), f.Decoder(true), options)
|
||||||
printersinternal.AddHandlers(p)
|
printersinternal.AddHandlers(p)
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
@ -50,13 +50,18 @@ type HumanReadablePrinter struct {
|
|||||||
options PrintOptions
|
options PrintOptions
|
||||||
lastType reflect.Type
|
lastType reflect.Type
|
||||||
hiddenObjNum int
|
hiddenObjNum int
|
||||||
|
encoder runtime.Encoder
|
||||||
|
decoder runtime.Decoder
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHumanReadablePrinter creates a HumanReadablePrinter.
|
// NewHumanReadablePrinter creates a HumanReadablePrinter.
|
||||||
func NewHumanReadablePrinter(options PrintOptions) *HumanReadablePrinter {
|
// If encoder and decoder are provided, an attempt to convert unstructured types to internal types is made.
|
||||||
|
func NewHumanReadablePrinter(encoder runtime.Encoder, decoder runtime.Decoder, options PrintOptions) *HumanReadablePrinter {
|
||||||
printer := &HumanReadablePrinter{
|
printer := &HumanReadablePrinter{
|
||||||
handlerMap: make(map[reflect.Type]*handlerEntry),
|
handlerMap: make(map[reflect.Type]*handlerEntry),
|
||||||
options: options,
|
options: options,
|
||||||
|
encoder: encoder,
|
||||||
|
decoder: decoder,
|
||||||
}
|
}
|
||||||
return printer
|
return printer
|
||||||
}
|
}
|
||||||
@ -167,7 +172,9 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
|
|||||||
|
|
||||||
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand before
|
// check if the object is unstructured. If so, let's attempt to convert it to a type we can understand before
|
||||||
// trying to print, since the printers are keyed by type. This is extremely expensive.
|
// trying to print, since the printers are keyed by type. This is extremely expensive.
|
||||||
//obj, _ = DecodeUnknownObject(obj)
|
if h.encoder != nil && h.decoder != nil {
|
||||||
|
obj, _ = decodeUnknownObject(obj, h.encoder, h.decoder)
|
||||||
|
}
|
||||||
|
|
||||||
t := reflect.TypeOf(obj)
|
t := reflect.TypeOf(obj)
|
||||||
if handler := h.handlerMap[t]; handler != nil {
|
if handler := h.handlerMap[t]; handler != nil {
|
||||||
@ -327,3 +334,18 @@ func appendAllLabels(showLabels bool, itemLabels map[string]string) string {
|
|||||||
|
|
||||||
return buffer.String()
|
return buffer.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if the object is unstructured. If so, attempt to convert it to a type we can understand.
|
||||||
|
func decodeUnknownObject(obj runtime.Object, encoder runtime.Encoder, decoder runtime.Decoder) (runtime.Object, error) {
|
||||||
|
var err error
|
||||||
|
switch obj.(type) {
|
||||||
|
case runtime.Unstructured, *runtime.Unknown:
|
||||||
|
if objBytes, err := runtime.Encode(encoder, obj); err == nil {
|
||||||
|
if decodedObj, err := runtime.Decode(decoder, objBytes); err == nil {
|
||||||
|
obj = decodedObj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj, err
|
||||||
|
}
|
||||||
|
@ -258,7 +258,7 @@ func ErrorPrintHandler(obj *TestPrintType, w io.Writer, options printers.PrintOp
|
|||||||
|
|
||||||
func TestCustomTypePrinting(t *testing.T) {
|
func TestCustomTypePrinting(t *testing.T) {
|
||||||
columns := []string{"Data"}
|
columns := []string{"Data"}
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||||
printer.Handler(columns, nil, PrintCustomType)
|
printer.Handler(columns, nil, PrintCustomType)
|
||||||
|
|
||||||
obj := TestPrintType{"test object"}
|
obj := TestPrintType{"test object"}
|
||||||
@ -275,7 +275,7 @@ func TestCustomTypePrinting(t *testing.T) {
|
|||||||
|
|
||||||
func TestCustomTypePrintingWithKind(t *testing.T) {
|
func TestCustomTypePrintingWithKind(t *testing.T) {
|
||||||
columns := []string{"Data"}
|
columns := []string{"Data"}
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||||
printer.Handler(columns, nil, PrintCustomType)
|
printer.Handler(columns, nil, PrintCustomType)
|
||||||
printer.EnsurePrintWithKind("test")
|
printer.EnsurePrintWithKind("test")
|
||||||
|
|
||||||
@ -293,7 +293,7 @@ func TestCustomTypePrintingWithKind(t *testing.T) {
|
|||||||
|
|
||||||
func TestPrintHandlerError(t *testing.T) {
|
func TestPrintHandlerError(t *testing.T) {
|
||||||
columns := []string{"Data"}
|
columns := []string{"Data"}
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||||
printer.Handler(columns, nil, ErrorPrintHandler)
|
printer.Handler(columns, nil, ErrorPrintHandler)
|
||||||
obj := TestPrintType{"test object"}
|
obj := TestPrintType{"test object"}
|
||||||
buffer := &bytes.Buffer{}
|
buffer := &bytes.Buffer{}
|
||||||
@ -304,7 +304,7 @@ func TestPrintHandlerError(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUnknownTypePrinting(t *testing.T) {
|
func TestUnknownTypePrinting(t *testing.T) {
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||||
buffer := &bytes.Buffer{}
|
buffer := &bytes.Buffer{}
|
||||||
err := printer.PrintObj(&TestUnknownType{}, buffer)
|
err := printer.PrintObj(&TestUnknownType{}, buffer)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -522,10 +522,10 @@ func TestPrinters(t *testing.T) {
|
|||||||
jsonpathPrinter = printers.NewVersionedPrinter(jsonpathPrinter, api.Scheme, v1.SchemeGroupVersion)
|
jsonpathPrinter = printers.NewVersionedPrinter(jsonpathPrinter, api.Scheme, v1.SchemeGroupVersion)
|
||||||
|
|
||||||
allPrinters := map[string]printers.ResourcePrinter{
|
allPrinters := map[string]printers.ResourcePrinter{
|
||||||
"humanReadable": printers.NewHumanReadablePrinter(printers.PrintOptions{
|
"humanReadable": printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
NoHeaders: true,
|
NoHeaders: true,
|
||||||
}),
|
}),
|
||||||
"humanReadableHeaders": printers.NewHumanReadablePrinter(printers.PrintOptions{}),
|
"humanReadableHeaders": printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{}),
|
||||||
"json": &printers.JSONPrinter{},
|
"json": &printers.JSONPrinter{},
|
||||||
"yaml": &printers.YAMLPrinter{},
|
"yaml": &printers.YAMLPrinter{},
|
||||||
"template": templatePrinter,
|
"template": templatePrinter,
|
||||||
@ -571,7 +571,7 @@ func TestPrinters(t *testing.T) {
|
|||||||
|
|
||||||
func TestPrintEventsResultSorted(t *testing.T) {
|
func TestPrintEventsResultSorted(t *testing.T) {
|
||||||
// Arrange
|
// Arrange
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||||
AddHandlers(printer)
|
AddHandlers(printer)
|
||||||
|
|
||||||
obj := api.EventList{
|
obj := api.EventList{
|
||||||
@ -616,7 +616,7 @@ func TestPrintEventsResultSorted(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPrintNodeStatus(t *testing.T) {
|
func TestPrintNodeStatus(t *testing.T) {
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{})
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{})
|
||||||
AddHandlers(printer)
|
AddHandlers(printer)
|
||||||
table := []struct {
|
table := []struct {
|
||||||
node api.Node
|
node api.Node
|
||||||
@ -736,7 +736,7 @@ func TestPrintNodeStatus(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPrintNodeOSImage(t *testing.T) {
|
func TestPrintNodeOSImage(t *testing.T) {
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
ColumnLabels: []string{},
|
ColumnLabels: []string{},
|
||||||
Wide: true,
|
Wide: true,
|
||||||
})
|
})
|
||||||
@ -781,7 +781,7 @@ func TestPrintNodeOSImage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPrintNodeKernelVersion(t *testing.T) {
|
func TestPrintNodeKernelVersion(t *testing.T) {
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
ColumnLabels: []string{},
|
ColumnLabels: []string{},
|
||||||
Wide: true,
|
Wide: true,
|
||||||
})
|
})
|
||||||
@ -826,7 +826,7 @@ func TestPrintNodeKernelVersion(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPrintNodeExternalIP(t *testing.T) {
|
func TestPrintNodeExternalIP(t *testing.T) {
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
Wide: true,
|
Wide: true,
|
||||||
})
|
})
|
||||||
AddHandlers(printer)
|
AddHandlers(printer)
|
||||||
@ -1219,7 +1219,7 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
|
|||||||
for _, test := range table {
|
for _, test := range table {
|
||||||
if test.isNamespaced {
|
if test.isNamespaced {
|
||||||
// Expect output to include namespace when requested.
|
// Expect output to include namespace when requested.
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
WithNamespace: true,
|
WithNamespace: true,
|
||||||
})
|
})
|
||||||
AddHandlers(printer)
|
AddHandlers(printer)
|
||||||
@ -1234,7 +1234,7 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Expect error when trying to get all namespaces for un-namespaced object.
|
// Expect error when trying to get all namespaces for un-namespaced object.
|
||||||
printer := printers.NewHumanReadablePrinter(printers.PrintOptions{
|
printer := printers.NewHumanReadablePrinter(nil, nil, printers.PrintOptions{
|
||||||
WithNamespace: true,
|
WithNamespace: true,
|
||||||
})
|
})
|
||||||
buffer := &bytes.Buffer{}
|
buffer := &bytes.Buffer{}
|
||||||
|
Loading…
Reference in New Issue
Block a user