printers: fix json types – int64 is only allowed integer

We have the invariant in apimachinery that all integers in JSON are int64.
We panic on other types on deepcopy and possibly at other occasions.
This commit is contained in:
Dr. Stefan Schimanski 2018-06-01 21:24:56 +00:00
parent d02cf08e27
commit ebbfaf3869
5 changed files with 37 additions and 37 deletions

View File

@ -608,7 +608,7 @@ func printPod(pod *api.Pod, options printers.PrintOptions) ([]metav1beta1.TableR
reason = "Terminating" reason = "Terminating"
} }
row.Cells = append(row.Cells, pod.Name, fmt.Sprintf("%d/%d", readyContainers, totalContainers), reason, restarts, translateTimestamp(pod.CreationTimestamp)) row.Cells = append(row.Cells, pod.Name, fmt.Sprintf("%d/%d", readyContainers, totalContainers), reason, int64(restarts), translateTimestamp(pod.CreationTimestamp))
if options.Wide { if options.Wide {
nodeName := pod.Spec.NodeName nodeName := pod.Spec.NodeName
@ -668,7 +668,7 @@ func printPodDisruptionBudget(obj *policy.PodDisruptionBudget, options printers.
maxUnavailable = "N/A" maxUnavailable = "N/A"
} }
row.Cells = append(row.Cells, obj.Name, minAvailable, maxUnavailable, obj.Status.PodDisruptionsAllowed, translateTimestamp(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, minAvailable, maxUnavailable, int64(obj.Status.PodDisruptionsAllowed), translateTimestamp(obj.CreationTimestamp))
return []metav1beta1.TableRow{row}, nil return []metav1beta1.TableRow{row}, nil
} }
@ -694,7 +694,7 @@ func printReplicationController(obj *api.ReplicationController, options printers
currentReplicas := obj.Status.Replicas currentReplicas := obj.Status.Replicas
readyReplicas := obj.Status.ReadyReplicas readyReplicas := obj.Status.ReadyReplicas
row.Cells = append(row.Cells, obj.Name, desiredReplicas, currentReplicas, readyReplicas, translateTimestamp(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, int64(desiredReplicas), int64(currentReplicas), int64(readyReplicas), translateTimestamp(obj.CreationTimestamp))
if options.Wide { if options.Wide {
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers) names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
row.Cells = append(row.Cells, names, images, labels.FormatLabels(obj.Spec.Selector)) row.Cells = append(row.Cells, names, images, labels.FormatLabels(obj.Spec.Selector))
@ -723,7 +723,7 @@ func printReplicaSet(obj *extensions.ReplicaSet, options printers.PrintOptions)
currentReplicas := obj.Status.Replicas currentReplicas := obj.Status.Replicas
readyReplicas := obj.Status.ReadyReplicas readyReplicas := obj.Status.ReadyReplicas
row.Cells = append(row.Cells, obj.Name, desiredReplicas, currentReplicas, readyReplicas, translateTimestamp(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, int64(desiredReplicas), int64(currentReplicas), int64(readyReplicas), translateTimestamp(obj.CreationTimestamp))
if options.Wide { if options.Wide {
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers) names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector)) row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector))
@ -755,7 +755,7 @@ func printJob(obj *batch.Job, options printers.PrintOptions) ([]metav1beta1.Tabl
completions = "<none>" completions = "<none>"
} }
row.Cells = append(row.Cells, obj.Name, completions, obj.Status.Succeeded, translateTimestamp(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, completions, int64(obj.Status.Succeeded), translateTimestamp(obj.CreationTimestamp))
if options.Wide { if options.Wide {
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers) names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector)) row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector))
@ -785,7 +785,7 @@ func printCronJob(obj *batch.CronJob, options printers.PrintOptions) ([]metav1be
lastScheduleTime = translateTimestamp(*obj.Status.LastScheduleTime) lastScheduleTime = translateTimestamp(*obj.Status.LastScheduleTime)
} }
row.Cells = append(row.Cells, obj.Name, obj.Spec.Schedule, printBoolPtr(obj.Spec.Suspend), len(obj.Status.Active), lastScheduleTime, translateTimestamp(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, obj.Spec.Schedule, printBoolPtr(obj.Spec.Suspend), int64(len(obj.Status.Active)), lastScheduleTime, translateTimestamp(obj.CreationTimestamp))
if options.Wide { if options.Wide {
names, images := layoutContainerCells(obj.Spec.JobTemplate.Spec.Template.Spec.Containers) names, images := layoutContainerCells(obj.Spec.JobTemplate.Spec.Template.Spec.Containers)
row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.JobTemplate.Spec.Selector)) row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.JobTemplate.Spec.Selector))
@ -972,7 +972,7 @@ func printStatefulSet(obj *apps.StatefulSet, options printers.PrintOptions) ([]m
desiredReplicas := obj.Spec.Replicas desiredReplicas := obj.Spec.Replicas
currentReplicas := obj.Status.Replicas currentReplicas := obj.Status.Replicas
createTime := translateTimestamp(obj.CreationTimestamp) createTime := translateTimestamp(obj.CreationTimestamp)
row.Cells = append(row.Cells, obj.Name, desiredReplicas, currentReplicas, createTime) row.Cells = append(row.Cells, obj.Name, int64(desiredReplicas), int64(currentReplicas), createTime)
if options.Wide { if options.Wide {
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers) names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
row.Cells = append(row.Cells, names, images) row.Cells = append(row.Cells, names, images)
@ -1003,7 +1003,7 @@ func printDaemonSet(obj *extensions.DaemonSet, options printers.PrintOptions) ([
numberUpdated := obj.Status.UpdatedNumberScheduled numberUpdated := obj.Status.UpdatedNumberScheduled
numberAvailable := obj.Status.NumberAvailable numberAvailable := obj.Status.NumberAvailable
row.Cells = append(row.Cells, obj.Name, desiredScheduled, currentScheduled, numberReady, numberUpdated, numberAvailable, labels.FormatLabels(obj.Spec.Template.Spec.NodeSelector), translateTimestamp(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, int64(desiredScheduled), int64(currentScheduled), int64(numberReady), int64(numberUpdated), int64(numberAvailable), labels.FormatLabels(obj.Spec.Template.Spec.NodeSelector), translateTimestamp(obj.CreationTimestamp))
if options.Wide { if options.Wide {
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers) names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector)) row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector))
@ -1067,7 +1067,7 @@ func printSecret(obj *api.Secret, options printers.PrintOptions) ([]metav1beta1.
row := metav1beta1.TableRow{ row := metav1beta1.TableRow{
Object: runtime.RawExtension{Object: obj}, Object: runtime.RawExtension{Object: obj},
} }
row.Cells = append(row.Cells, obj.Name, string(obj.Type), len(obj.Data), translateTimestamp(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, string(obj.Type), int64(len(obj.Data)), translateTimestamp(obj.CreationTimestamp))
return []metav1beta1.TableRow{row}, nil return []metav1beta1.TableRow{row}, nil
} }
@ -1087,7 +1087,7 @@ func printServiceAccount(obj *api.ServiceAccount, options printers.PrintOptions)
row := metav1beta1.TableRow{ row := metav1beta1.TableRow{
Object: runtime.RawExtension{Object: obj}, Object: runtime.RawExtension{Object: obj},
} }
row.Cells = append(row.Cells, obj.Name, len(obj.Secrets), translateTimestamp(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, int64(len(obj.Secrets)), translateTimestamp(obj.CreationTimestamp))
return []metav1beta1.TableRow{row}, nil return []metav1beta1.TableRow{row}, nil
} }
@ -1299,7 +1299,7 @@ func printEvent(obj *api.Event, options printers.PrintOptions) ([]metav1beta1.Ta
LastTimestamp = translateTimestamp(obj.LastTimestamp) LastTimestamp = translateTimestamp(obj.LastTimestamp)
} }
row.Cells = append(row.Cells, LastTimestamp, FirstTimestamp, row.Cells = append(row.Cells, LastTimestamp, FirstTimestamp,
obj.Count, obj.Name, obj.InvolvedObject.Kind, int64(obj.Count), obj.Name, obj.InvolvedObject.Kind,
obj.InvolvedObject.FieldPath, obj.Type, obj.Reason, obj.InvolvedObject.FieldPath, obj.Type, obj.Reason,
formatEventSource(obj.Source), obj.Message) formatEventSource(obj.Source), obj.Message)
@ -1482,7 +1482,7 @@ func printDeployment(obj *extensions.Deployment, options printers.PrintOptions)
// this shouldn't happen if LabelSelector passed validation // this shouldn't happen if LabelSelector passed validation
return nil, err return nil, err
} }
row.Cells = append(row.Cells, obj.Name, desiredReplicas, currentReplicas, updatedReplicas, availableReplicas, age) row.Cells = append(row.Cells, obj.Name, int64(desiredReplicas), int64(currentReplicas), int64(updatedReplicas), int64(availableReplicas), age)
if options.Wide { if options.Wide {
containers, images := layoutContainerCells(containers) containers, images := layoutContainerCells(containers)
row.Cells = append(row.Cells, containers, images, selector.String()) row.Cells = append(row.Cells, containers, images, selector.String())
@ -1591,7 +1591,7 @@ func printHorizontalPodAutoscaler(obj *autoscaling.HorizontalPodAutoscaler, opti
} }
maxPods := obj.Spec.MaxReplicas maxPods := obj.Spec.MaxReplicas
currentReplicas := obj.Status.CurrentReplicas currentReplicas := obj.Status.CurrentReplicas
row.Cells = append(row.Cells, obj.Name, reference, metrics, minPods, maxPods, currentReplicas, translateTimestamp(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, reference, metrics, minPods, int64(maxPods), int64(currentReplicas), translateTimestamp(obj.CreationTimestamp))
return []metav1beta1.TableRow{row}, nil return []metav1beta1.TableRow{row}, nil
} }
@ -1611,7 +1611,7 @@ func printConfigMap(obj *api.ConfigMap, options printers.PrintOptions) ([]metav1
row := metav1beta1.TableRow{ row := metav1beta1.TableRow{
Object: runtime.RawExtension{Object: obj}, Object: runtime.RawExtension{Object: obj},
} }
row.Cells = append(row.Cells, obj.Name, len(obj.Data), translateTimestamp(obj.CreationTimestamp)) row.Cells = append(row.Cells, obj.Name, int64(len(obj.Data)), translateTimestamp(obj.CreationTimestamp))
return []metav1beta1.TableRow{row}, nil return []metav1beta1.TableRow{row}, nil
} }

View File

@ -1545,7 +1545,7 @@ func TestPrintPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", int64(6), "<unknown>"}}},
}, },
{ {
// Test container error overwrites pod phase // Test container error overwrites pod phase
@ -1560,7 +1560,7 @@ func TestPrintPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test2", "1/2", "ContainerWaitingReason", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test2", "1/2", "ContainerWaitingReason", int64(6), "<unknown>"}}},
}, },
{ {
// Test the same as the above but with Terminated state and the first container overwrites the rest // Test the same as the above but with Terminated state and the first container overwrites the rest
@ -1575,7 +1575,7 @@ func TestPrintPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test3", "0/2", "ContainerWaitingReason", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test3", "0/2", "ContainerWaitingReason", int64(6), "<unknown>"}}},
}, },
{ {
// Test ready is not enough for reporting running // Test ready is not enough for reporting running
@ -1590,7 +1590,7 @@ func TestPrintPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test4", "1/2", "podPhase", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test4", "1/2", "podPhase", int64(6), "<unknown>"}}},
}, },
{ {
// Test ready is not enough for reporting running // Test ready is not enough for reporting running
@ -1606,7 +1606,7 @@ func TestPrintPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test5", "1/2", "podReason", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test5", "1/2", "podReason", int64(6), "<unknown>"}}},
}, },
{ {
// Test pod has 2 containers, one is running and the other is completed. // Test pod has 2 containers, one is running and the other is completed.
@ -1622,7 +1622,7 @@ func TestPrintPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test6", "1/2", "Running", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test6", "1/2", "Running", int64(6), "<unknown>"}}},
}, },
} }
@ -1663,7 +1663,7 @@ func TestPrintPodwide(t *testing.T) {
NominatedNodeName: "node1", NominatedNodeName: "node1",
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", 6, "<unknown>", "1.1.1.1", "test1", "node1"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", int64(6), "<unknown>", "1.1.1.1", "test1", "node1"}}},
}, },
{ {
// Test when the NodeName and PodIP are none // Test when the NodeName and PodIP are none
@ -1682,7 +1682,7 @@ func TestPrintPodwide(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test2", "1/2", "ContainerWaitingReason", 6, "<unknown>", "<none>", "<none>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test2", "1/2", "ContainerWaitingReason", int64(6), "<unknown>", "<none>", "<none>"}}},
}, },
} }
@ -1732,7 +1732,7 @@ func TestPrintPodList(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test1", "2/2", "podPhase", 6, "<unknown>"}}, {Cells: []interface{}{"test2", "1/1", "podPhase", 1, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test1", "2/2", "podPhase", int64(6), "<unknown>"}}, {Cells: []interface{}{"test2", "1/1", "podPhase", int64(1), "<unknown>"}}},
}, },
} }
@ -1769,7 +1769,7 @@ func TestPrintNonTerminatedPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "Running", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "Running", int64(6), "<unknown>"}}},
}, },
{ {
// Test pod phase Pending should be printed // Test pod phase Pending should be printed
@ -1784,7 +1784,7 @@ func TestPrintNonTerminatedPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test2", "1/2", "Pending", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test2", "1/2", "Pending", int64(6), "<unknown>"}}},
}, },
{ {
// Test pod phase Unknown should be printed // Test pod phase Unknown should be printed
@ -1799,7 +1799,7 @@ func TestPrintNonTerminatedPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test3", "1/2", "Unknown", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test3", "1/2", "Unknown", int64(6), "<unknown>"}}},
}, },
{ {
// Test pod phase Succeeded shouldn't be printed // Test pod phase Succeeded shouldn't be printed
@ -1814,7 +1814,7 @@ func TestPrintNonTerminatedPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test4", "1/2", "Succeeded", 6, "<unknown>"}, Conditions: podSuccessConditions}}, []metav1beta1.TableRow{{Cells: []interface{}{"test4", "1/2", "Succeeded", int64(6), "<unknown>"}, Conditions: podSuccessConditions}},
}, },
{ {
// Test pod phase Failed shouldn't be printed // Test pod phase Failed shouldn't be printed
@ -1829,7 +1829,7 @@ func TestPrintNonTerminatedPod(t *testing.T) {
}, },
}, },
}, },
[]metav1beta1.TableRow{{Cells: []interface{}{"test5", "1/2", "Failed", 6, "<unknown>"}, Conditions: podFailedConditions}}, []metav1beta1.TableRow{{Cells: []interface{}{"test5", "1/2", "Failed", int64(6), "<unknown>"}, Conditions: podFailedConditions}},
}, },
} }
@ -1871,7 +1871,7 @@ func TestPrintPodWithLabels(t *testing.T) {
}, },
}, },
[]string{"col1", "COL2"}, []string{"col1", "COL2"},
[]metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", 6, "<unknown>", "asd", "zxc"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", int64(6), "<unknown>", "asd", "zxc"}}},
}, },
{ {
// Test name, num of containers, restarts, container ready status // Test name, num of containers, restarts, container ready status
@ -1890,7 +1890,7 @@ func TestPrintPodWithLabels(t *testing.T) {
}, },
}, },
[]string{}, []string{},
[]metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", int64(6), "<unknown>"}}},
}, },
} }
@ -2654,7 +2654,7 @@ func TestPrintPodShowLabels(t *testing.T) {
}, },
}, },
true, true,
[]metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", 6, "<unknown>", "COL2=zxc,col1=asd"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", int64(6), "<unknown>", "COL2=zxc,col1=asd"}}},
}, },
{ {
// Test name, num of containers, restarts, container ready status // Test name, num of containers, restarts, container ready status
@ -2673,7 +2673,7 @@ func TestPrintPodShowLabels(t *testing.T) {
}, },
}, },
false, false,
[]metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", 6, "<unknown>"}}}, []metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", int64(6), "<unknown>"}}},
}, },
} }

View File

@ -452,7 +452,7 @@ func TestConvertToTableList(t *testing.T) {
out: &metav1beta1.Table{ out: &metav1beta1.Table{
ColumnDefinitions: columns, ColumnDefinitions: columns,
Rows: []metav1beta1.TableRow{ Rows: []metav1beta1.TableRow{
{Cells: []interface{}{"", "0/0", "", 0, "<unknown>", "<none>", "<none>"}, Object: runtime.RawExtension{Object: &api.Pod{}}}, {Cells: []interface{}{"", "0/0", "", int64(0), "<unknown>", "<none>", "<none>"}, Object: runtime.RawExtension{Object: &api.Pod{}}},
}, },
}, },
}, },
@ -461,7 +461,7 @@ func TestConvertToTableList(t *testing.T) {
out: &metav1beta1.Table{ out: &metav1beta1.Table{
ColumnDefinitions: columns, ColumnDefinitions: columns,
Rows: []metav1beta1.TableRow{ Rows: []metav1beta1.TableRow{
{Cells: []interface{}{"foo", "1/2", "Pending", 10, "1y", "10.1.2.3", "test-node"}, Object: runtime.RawExtension{Object: pod1}}, {Cells: []interface{}{"foo", "1/2", "Pending", int64(10), "1y", "10.1.2.3", "test-node"}, Object: runtime.RawExtension{Object: pod1}},
}, },
}, },
}, },

View File

@ -66,8 +66,8 @@ type TableColumnDefinition struct {
// TableRow is an individual row in a table. // TableRow is an individual row in a table.
// +protobuf=false // +protobuf=false
type TableRow struct { type TableRow struct {
// cells will be as wide as headers and may contain strings, numbers, booleans, simple maps, or lists, or // cells will be as wide as headers and may contain strings, numbers (float64 or int64), booleans, simple
// null. See the type field of the column definition for a more detailed description. // maps, or lists, or null. See the type field of the column definition for a more detailed description.
Cells []interface{} `json:"cells"` Cells []interface{} `json:"cells"`
// conditions describe additional status of a row that are relevant for a human user. // conditions describe additional status of a row that are relevant for a human user.
// +optional // +optional

View File

@ -80,7 +80,7 @@ func (TableOptions) SwaggerDoc() map[string]string {
var map_TableRow = map[string]string{ var map_TableRow = map[string]string{
"": "TableRow is an individual row in a table.", "": "TableRow is an individual row in a table.",
"cells": "cells will be as wide as headers and may contain strings, numbers, booleans, simple maps, or lists, or null. See the type field of the column definition for a more detailed description.", "cells": "cells will be as wide as headers and may contain strings, numbers (float64 or int64), booleans, simple maps, or lists, or null. See the type field of the column definition for a more detailed description.",
"conditions": "conditions describe additional status of a row that are relevant for a human user.", "conditions": "conditions describe additional status of a row that are relevant for a human user.",
"object": "This field contains the requested additional information about each object based on the includeObject policy when requesting the Table. If \"None\", this field is empty, if \"Object\" this will be the default serialization of the object for the current API version, and if \"Metadata\" (the default) will contain the object metadata. Check the returned kind and apiVersion of the object before parsing.", "object": "This field contains the requested additional information about each object based on the includeObject policy when requesting the Table. If \"None\", this field is empty, if \"Object\" this will be the default serialization of the object for the current API version, and if \"Metadata\" (the default) will contain the object metadata. Check the returned kind and apiVersion of the object before parsing.",
} }