apiserver: printers should use int64

printers should use int64 to avoid a panic from DeepCopyJSONValue
This commit is contained in:
Abu Kashem 2022-06-06 14:35:26 -04:00
parent 59ffc93678
commit 788e151bc1
No known key found for this signature in database
GPG Key ID: 33A4FA7088DB68A9
2 changed files with 334 additions and 10 deletions

View File

@ -1377,7 +1377,7 @@ func printCSINode(obj *storage.CSINode, options printers.GenerateOptions) ([]met
row := metav1.TableRow{
Object: runtime.RawExtension{Object: obj},
}
row.Cells = append(row.Cells, obj.Name, len(obj.Spec.Drivers), translateTimestampSince(obj.CreationTimestamp))
row.Cells = append(row.Cells, obj.Name, int64(len(obj.Spec.Drivers)), translateTimestampSince(obj.CreationTimestamp))
return []metav1.TableRow{row}, nil
}
@ -1481,7 +1481,7 @@ func printMutatingWebhook(obj *admissionregistration.MutatingWebhookConfiguratio
row := metav1.TableRow{
Object: runtime.RawExtension{Object: obj},
}
row.Cells = append(row.Cells, obj.Name, len(obj.Webhooks), translateTimestampSince(obj.CreationTimestamp))
row.Cells = append(row.Cells, obj.Name, int64(len(obj.Webhooks)), translateTimestampSince(obj.CreationTimestamp))
return []metav1.TableRow{row}, nil
}
@ -1501,7 +1501,7 @@ func printValidatingWebhook(obj *admissionregistration.ValidatingWebhookConfigur
row := metav1.TableRow{
Object: runtime.RawExtension{Object: obj},
}
row.Cells = append(row.Cells, obj.Name, len(obj.Webhooks), translateTimestampSince(obj.CreationTimestamp))
row.Cells = append(row.Cells, obj.Name, int64(len(obj.Webhooks)), translateTimestampSince(obj.CreationTimestamp))
return []metav1.TableRow{row}, nil
}
@ -2299,7 +2299,7 @@ func printStatus(obj *metav1.Status, options printers.GenerateOptions) ([]metav1
row := metav1.TableRow{
Object: runtime.RawExtension{Object: obj},
}
row.Cells = append(row.Cells, obj.Status, obj.Reason, obj.Message)
row.Cells = append(row.Cells, obj.Status, string(obj.Reason), obj.Message)
return []metav1.TableRow{row}, nil
}
@ -2528,7 +2528,7 @@ func printFlowSchema(obj *flowcontrol.FlowSchema, options printers.GenerateOptio
break
}
}
row.Cells = append(row.Cells, name, plName, obj.Spec.MatchingPrecedence, distinguisherMethod, translateTimestampSince(obj.CreationTimestamp), badPLRef)
row.Cells = append(row.Cells, name, plName, int64(obj.Spec.MatchingPrecedence), distinguisherMethod, translateTimestampSince(obj.CreationTimestamp), badPLRef)
return []metav1.TableRow{row}, nil
}
@ -2628,7 +2628,7 @@ func printScale(obj *autoscaling.Scale, options printers.GenerateOptions) ([]met
row := metav1.TableRow{
Object: runtime.RawExtension{Object: obj},
}
row.Cells = append(row.Cells, obj.Name, obj.Spec.Replicas, obj.Status.Replicas, translateTimestampSince(obj.CreationTimestamp))
row.Cells = append(row.Cells, obj.Name, int64(obj.Spec.Replicas), int64(obj.Status.Replicas), translateTimestampSince(obj.CreationTimestamp))
return []metav1.TableRow{row}, nil
}

View File

@ -17,8 +17,10 @@ limitations under the License.
package internalversion
import (
"fmt"
"math"
"reflect"
"runtime"
"testing"
"time"
@ -28,6 +30,7 @@ import (
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/util/certificate/csr"
"k8s.io/kubernetes/pkg/apis/admissionregistration"
"k8s.io/kubernetes/pkg/apis/apiserverinternal"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/autoscaling"
@ -5534,7 +5537,7 @@ func TestPrintFlowSchema(t *testing.T) {
},
},
// Columns: Name, PriorityLevelName, MatchingPrecedence, DistinguisherMethod, Age, MissingPL
expected: []metav1.TableRow{{Cells: []interface{}{"all-matcher", "allee", int32(math.MaxInt32), "ByUser", "0s", "?"}}},
expected: []metav1.TableRow{{Cells: []interface{}{"all-matcher", "allee", int64(math.MaxInt32), "ByUser", "0s", "?"}}},
}, {
fs: flowcontrol.FlowSchema{
ObjectMeta: metav1.ObjectMeta{
@ -5580,7 +5583,7 @@ func TestPrintFlowSchema(t *testing.T) {
},
},
// Columns: Name, PriorityLevelName, MatchingPrecedence, DistinguisherMethod, Age, MissingPL
expected: []metav1.TableRow{{Cells: []interface{}{"some-matcher", "allee", int32(0), "ByNamespace", "5m", "True"}}},
expected: []metav1.TableRow{{Cells: []interface{}{"some-matcher", "allee", int64(0), "ByNamespace", "5m", "True"}}},
}, {
fs: flowcontrol.FlowSchema{
ObjectMeta: metav1.ObjectMeta{
@ -5607,7 +5610,7 @@ func TestPrintFlowSchema(t *testing.T) {
},
},
// Columns: Name, PriorityLevelName, MatchingPrecedence, DistinguisherMethod, Age, MissingPL
expected: []metav1.TableRow{{Cells: []interface{}{"exempt", "allee", int32(0), "<none>", "5m", "?"}}},
expected: []metav1.TableRow{{Cells: []interface{}{"exempt", "allee", int64(0), "<none>", "5m", "?"}}},
},
}
@ -5841,7 +5844,7 @@ func TestPrintScale(t *testing.T) {
},
expected: []metav1.TableRow{
{
Cells: []interface{}{"test-autoscaling", int32(2), int32(1), string("0s")},
Cells: []interface{}{"test-autoscaling", int64(2), int64(1), string("0s")},
},
},
},
@ -5860,3 +5863,324 @@ func TestPrintScale(t *testing.T) {
}
}
}
func TestTableRowDeepCopyShouldNotPanic(t *testing.T) {
tests := []struct {
name string
printer func() ([]metav1.TableRow, error)
}{
{
name: "Pod",
printer: func() ([]metav1.TableRow, error) {
return printPod(&api.Pod{}, printers.GenerateOptions{})
},
},
{
name: "PodTemplate",
printer: func() ([]metav1.TableRow, error) {
return printPodTemplate(&api.PodTemplate{}, printers.GenerateOptions{})
},
},
{
name: "PodDisruptionBudget",
printer: func() ([]metav1.TableRow, error) {
return printPodDisruptionBudget(&policy.PodDisruptionBudget{}, printers.GenerateOptions{})
},
},
{
name: "ReplicationController",
printer: func() ([]metav1.TableRow, error) {
return printReplicationController(&api.ReplicationController{}, printers.GenerateOptions{})
},
},
{
name: "ReplicaSet",
printer: func() ([]metav1.TableRow, error) {
return printReplicaSet(&apps.ReplicaSet{}, printers.GenerateOptions{})
},
},
{
name: "Job",
printer: func() ([]metav1.TableRow, error) {
return printJob(&batch.Job{}, printers.GenerateOptions{})
},
},
{
name: "CronJob",
printer: func() ([]metav1.TableRow, error) {
return printCronJob(&batch.CronJob{}, printers.GenerateOptions{})
},
},
{
name: "Service",
printer: func() ([]metav1.TableRow, error) {
return printService(&api.Service{}, printers.GenerateOptions{})
},
},
{
name: "Ingress",
printer: func() ([]metav1.TableRow, error) {
return printIngress(&networking.Ingress{}, printers.GenerateOptions{})
},
},
{
name: "IngressClass",
printer: func() ([]metav1.TableRow, error) {
return printIngressClass(&networking.IngressClass{}, printers.GenerateOptions{})
},
},
{
name: "StatefulSet",
printer: func() ([]metav1.TableRow, error) {
return printStatefulSet(&apps.StatefulSet{}, printers.GenerateOptions{})
},
},
{
name: "DaemonSet",
printer: func() ([]metav1.TableRow, error) {
return printDaemonSet(&apps.DaemonSet{}, printers.GenerateOptions{})
},
},
{
name: "Endpoints",
printer: func() ([]metav1.TableRow, error) {
return printEndpoints(&api.Endpoints{}, printers.GenerateOptions{})
},
},
{
name: "EndpointSlice",
printer: func() ([]metav1.TableRow, error) {
return printEndpointSlice(&discovery.EndpointSlice{}, printers.GenerateOptions{})
},
},
{
name: "CSINode",
printer: func() ([]metav1.TableRow, error) {
return printCSINode(&storage.CSINode{}, printers.GenerateOptions{})
},
},
{
name: "CSIDriver",
printer: func() ([]metav1.TableRow, error) {
return printCSIDriver(&storage.CSIDriver{}, printers.GenerateOptions{})
},
},
{
name: "CSIStorageCapacity",
printer: func() ([]metav1.TableRow, error) {
return printCSIStorageCapacity(&storage.CSIStorageCapacity{}, printers.GenerateOptions{})
},
},
{
name: "MutatingWebhookConfiguration",
printer: func() ([]metav1.TableRow, error) {
return printMutatingWebhook(&admissionregistration.MutatingWebhookConfiguration{}, printers.GenerateOptions{})
},
},
{
name: "ValidatingWebhookConfiguration",
printer: func() ([]metav1.TableRow, error) {
return printValidatingWebhook(&admissionregistration.ValidatingWebhookConfiguration{}, printers.GenerateOptions{})
},
},
{
name: "Namespace",
printer: func() ([]metav1.TableRow, error) {
return printNamespace(&api.Namespace{}, printers.GenerateOptions{})
},
},
{
name: "Secret",
printer: func() ([]metav1.TableRow, error) {
return printSecret(&api.Secret{}, printers.GenerateOptions{})
},
},
{
name: "ServiceAccount",
printer: func() ([]metav1.TableRow, error) {
return printServiceAccount(&api.ServiceAccount{}, printers.GenerateOptions{})
},
},
{
name: "Node",
printer: func() ([]metav1.TableRow, error) {
return printNode(&api.Node{}, printers.GenerateOptions{})
},
},
{
name: "PersistentVolume",
printer: func() ([]metav1.TableRow, error) {
return printPersistentVolume(&api.PersistentVolume{}, printers.GenerateOptions{})
},
},
{
name: "PersistentVolumeClaim",
printer: func() ([]metav1.TableRow, error) {
return printPersistentVolumeClaim(&api.PersistentVolumeClaim{}, printers.GenerateOptions{})
},
},
{
name: "Event",
printer: func() ([]metav1.TableRow, error) {
return printEvent(&api.Event{}, printers.GenerateOptions{})
},
},
{
name: "RoleBinding",
printer: func() ([]metav1.TableRow, error) {
return printRoleBinding(&rbac.RoleBinding{}, printers.GenerateOptions{})
},
},
{
name: "ClusterRoleBinding",
printer: func() ([]metav1.TableRow, error) {
return printClusterRoleBinding(&rbac.ClusterRoleBinding{}, printers.GenerateOptions{})
},
},
{
name: "CertificateSigningRequest",
printer: func() ([]metav1.TableRow, error) {
return printCertificateSigningRequest(&certificates.CertificateSigningRequest{}, printers.GenerateOptions{})
},
},
{
name: "ComponentStatus",
printer: func() ([]metav1.TableRow, error) {
return printComponentStatus(&api.ComponentStatus{}, printers.GenerateOptions{})
},
},
{
name: "Deployment",
printer: func() ([]metav1.TableRow, error) {
return printDeployment(&apps.Deployment{}, printers.GenerateOptions{})
},
},
{
name: "HorizontalPodAutoscaler",
printer: func() ([]metav1.TableRow, error) {
return printHorizontalPodAutoscaler(&autoscaling.HorizontalPodAutoscaler{}, printers.GenerateOptions{})
},
},
{
name: "ConfigMap",
printer: func() ([]metav1.TableRow, error) {
return printConfigMap(&api.ConfigMap{}, printers.GenerateOptions{})
},
},
{
name: "PodSecurityPolicy",
printer: func() ([]metav1.TableRow, error) {
return printPodSecurityPolicy(&policy.PodSecurityPolicy{}, printers.GenerateOptions{})
},
},
{
name: "NetworkPolicy",
printer: func() ([]metav1.TableRow, error) {
return printNetworkPolicy(&networking.NetworkPolicy{}, printers.GenerateOptions{})
},
},
{
name: "StorageClass",
printer: func() ([]metav1.TableRow, error) {
return printStorageClass(&storage.StorageClass{}, printers.GenerateOptions{})
},
},
{
name: "Lease",
printer: func() ([]metav1.TableRow, error) {
return printLease(&coordination.Lease{}, printers.GenerateOptions{})
},
},
{
name: "ControllerRevision",
printer: func() ([]metav1.TableRow, error) {
return printControllerRevision(&apps.ControllerRevision{}, printers.GenerateOptions{})
},
},
{
name: "ResourceQuota",
printer: func() ([]metav1.TableRow, error) {
return printResourceQuota(&api.ResourceQuota{}, printers.GenerateOptions{})
},
},
{
name: "PriorityClass",
printer: func() ([]metav1.TableRow, error) {
return printPriorityClass(&scheduling.PriorityClass{}, printers.GenerateOptions{})
},
},
{
name: "RuntimeClass",
printer: func() ([]metav1.TableRow, error) {
return printRuntimeClass(&nodeapi.RuntimeClass{}, printers.GenerateOptions{})
},
},
{
name: "VolumeAttachment",
printer: func() ([]metav1.TableRow, error) {
return printVolumeAttachment(&storage.VolumeAttachment{}, printers.GenerateOptions{})
},
},
{
name: "FlowSchema",
printer: func() ([]metav1.TableRow, error) {
return printFlowSchema(&flowcontrol.FlowSchema{}, printers.GenerateOptions{})
},
},
{
name: "StorageVersion",
printer: func() ([]metav1.TableRow, error) {
return printStorageVersion(&apiserverinternal.StorageVersion{}, printers.GenerateOptions{})
},
},
{
name: "PriorityLevelConfiguration",
printer: func() ([]metav1.TableRow, error) {
return printPriorityLevelConfiguration(&flowcontrol.PriorityLevelConfiguration{}, printers.GenerateOptions{})
},
},
{
name: "Scale",
printer: func() ([]metav1.TableRow, error) {
return printScale(&autoscaling.Scale{}, printers.GenerateOptions{})
},
},
{
name: "Status",
printer: func() ([]metav1.TableRow, error) {
return printStatus(&metav1.Status{}, printers.GenerateOptions{})
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
rows, err := test.printer()
if err != nil {
t.Fatalf("expected no error, but got: %#v", err)
}
if len(rows) <= 0 {
t.Fatalf("expected to have at least one TableRow, but got: %d", len(rows))
}
func() {
defer func() {
if err := recover(); err != nil {
// Same as stdlib http server code. Manually allocate stack
// trace buffer size to prevent excessively large logs
const size = 64 << 10
buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)]
err = fmt.Errorf("%q stack:\n%s", err, buf)
t.Errorf("Expected no panic, but got: %v", err)
}
}()
// should not panic
rows[0].DeepCopy()
}()
})
}
}