Refactor printers to support rendering as a Table

Return tables from the server.
parent f203e42c
...@@ -192,7 +192,7 @@ func Example_printReplicationControllerWithNamespace() { ...@@ -192,7 +192,7 @@ func Example_printReplicationControllerWithNamespace() {
}, },
} }
mapper, _ := f.Object() mapper, _ := f.Object()
err := f.PrintObject(cmd, mapper, ctrl, os.Stdout) err := f.PrintObject(cmd, mapper, ctrl, printers.GetNewTabWriter(os.Stdout))
if err != nil { if err != nil {
fmt.Printf("Unexpected error: %v", err) fmt.Printf("Unexpected error: %v", err)
} }
...@@ -247,7 +247,7 @@ func Example_printMultiContainersReplicationControllerWithWide() { ...@@ -247,7 +247,7 @@ func Example_printMultiContainersReplicationControllerWithWide() {
}, },
} }
mapper, _ := f.Object() mapper, _ := f.Object()
err := f.PrintObject(cmd, mapper, ctrl, os.Stdout) err := f.PrintObject(cmd, mapper, ctrl, printers.GetNewTabWriter(os.Stdout))
if err != nil { if err != nil {
fmt.Printf("Unexpected error: %v", err) fmt.Printf("Unexpected error: %v", err)
} }
...@@ -301,7 +301,7 @@ func Example_printReplicationController() { ...@@ -301,7 +301,7 @@ func Example_printReplicationController() {
}, },
} }
mapper, _ := f.Object() mapper, _ := f.Object()
err := f.PrintObject(cmd, mapper, ctrl, os.Stdout) err := f.PrintObject(cmd, mapper, ctrl, printers.GetNewTabWriter(os.Stdout))
if err != nil { if err != nil {
fmt.Printf("Unexpected error: %v", err) fmt.Printf("Unexpected error: %v", err)
} }
...@@ -344,7 +344,7 @@ func Example_printPodWithWideFormat() { ...@@ -344,7 +344,7 @@ func Example_printPodWithWideFormat() {
}, },
} }
mapper, _ := f.Object() mapper, _ := f.Object()
err := f.PrintObject(cmd, mapper, pod, os.Stdout) err := f.PrintObject(cmd, mapper, pod, printers.GetNewTabWriter(os.Stdout))
if err != nil { if err != nil {
fmt.Printf("Unexpected error: %v", err) fmt.Printf("Unexpected error: %v", err)
} }
...@@ -390,7 +390,7 @@ func Example_printPodWithShowLabels() { ...@@ -390,7 +390,7 @@ func Example_printPodWithShowLabels() {
}, },
} }
mapper, _ := f.Object() mapper, _ := f.Object()
err := f.PrintObject(cmd, mapper, pod, os.Stdout) err := f.PrintObject(cmd, mapper, pod, printers.GetNewTabWriter(os.Stdout))
if err != nil { if err != nil {
fmt.Printf("Unexpected error: %v", err) fmt.Printf("Unexpected error: %v", err)
} }
...@@ -514,7 +514,7 @@ func Example_printPodHideTerminated() { ...@@ -514,7 +514,7 @@ func Example_printPodHideTerminated() {
} }
for _, pod := range filteredPodList { for _, pod := range filteredPodList {
mapper, _ := f.Object() mapper, _ := f.Object()
err := f.PrintObject(cmd, mapper, pod, os.Stdout) err := f.PrintObject(cmd, mapper, pod, printers.GetNewTabWriter(os.Stdout))
if err != nil { if err != nil {
fmt.Printf("Unexpected error: %v", err) fmt.Printf("Unexpected error: %v", err)
} }
...@@ -542,7 +542,7 @@ func Example_printPodShowAll() { ...@@ -542,7 +542,7 @@ func Example_printPodShowAll() {
cmd := NewCmdRun(f, os.Stdin, os.Stdout, os.Stderr) cmd := NewCmdRun(f, os.Stdin, os.Stdout, os.Stderr)
podList := newAllPhasePodList() podList := newAllPhasePodList()
mapper, _ := f.Object() mapper, _ := f.Object()
err := f.PrintObject(cmd, mapper, podList, os.Stdout) err := f.PrintObject(cmd, mapper, podList, printers.GetNewTabWriter(os.Stdout))
if err != nil { if err != nil {
fmt.Printf("Unexpected error: %v", err) fmt.Printf("Unexpected error: %v", err)
} }
...@@ -616,9 +616,10 @@ func Example_printServiceWithNamespacesAndLabels() { ...@@ -616,9 +616,10 @@ func Example_printServiceWithNamespacesAndLabels() {
} }
ld := strings.NewLineDelimiter(os.Stdout, "|") ld := strings.NewLineDelimiter(os.Stdout, "|")
defer ld.Flush() defer ld.Flush()
out := printers.GetNewTabWriter(ld)
defer out.Flush()
mapper, _ := f.Object() mapper, _ := f.Object()
err := f.PrintObject(cmd, mapper, svc, ld) err := f.PrintObject(cmd, mapper, svc, out)
if err != nil { if err != nil {
fmt.Printf("Unexpected error: %v", err) fmt.Printf("Unexpected error: %v", err)
} }
......
...@@ -28,12 +28,14 @@ go_library( ...@@ -28,12 +28,14 @@ go_library(
"//pkg/util/slice:go_default_library", "//pkg/util/slice:go_default_library",
"//vendor/github.com/fatih/camelcase:go_default_library", "//vendor/github.com/fatih/camelcase:go_default_library",
"//vendor/github.com/ghodss/yaml:go_default_library", "//vendor/github.com/ghodss/yaml:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//vendor/k8s.io/client-go/util/jsonpath:go_default_library", "//vendor/k8s.io/client-go/util/jsonpath:go_default_library",
], ],
) )
...@@ -63,6 +65,7 @@ filegroup( ...@@ -63,6 +65,7 @@ filegroup(
srcs = [ srcs = [
":package-srcs", ":package-srcs",
"//pkg/printers/internalversion:all-srcs", "//pkg/printers/internalversion:all-srcs",
"//pkg/printers/storage:all-srcs",
], ],
tags = ["automanaged"], tags = ["automanaged"],
) )
......
...@@ -40,6 +40,7 @@ go_test( ...@@ -40,6 +40,7 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/yaml:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/serializer/yaml:go_default_library",
...@@ -65,6 +66,7 @@ go_library( ...@@ -65,6 +66,7 @@ go_library(
"//pkg/api/helper/qos:go_default_library", "//pkg/api/helper/qos:go_default_library",
"//pkg/api/ref:go_default_library", "//pkg/api/ref:go_default_library",
"//pkg/api/resource:go_default_library", "//pkg/api/resource:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/apps:go_default_library", "//pkg/apis/apps:go_default_library",
"//pkg/apis/autoscaling:go_default_library", "//pkg/apis/autoscaling:go_default_library",
"//pkg/apis/batch:go_default_library", "//pkg/apis/batch:go_default_library",
...@@ -94,8 +96,10 @@ go_library( ...@@ -94,8 +96,10 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library", "//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
......
...@@ -27,12 +27,15 @@ import ( ...@@ -27,12 +27,15 @@ import (
"time" "time"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1alpha1 "k8s.io/apimachinery/pkg/apis/meta/v1alpha1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/federation/apis/federation" "k8s.io/kubernetes/federation/apis/federation"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/events" "k8s.io/kubernetes/pkg/api/events"
"k8s.io/kubernetes/pkg/api/helper" "k8s.io/kubernetes/pkg/api/helper"
apiv1 "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/apis/apps" "k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/autoscaling" "k8s.io/kubernetes/pkg/apis/autoscaling"
"k8s.io/kubernetes/pkg/apis/batch" "k8s.io/kubernetes/pkg/apis/batch"
...@@ -53,8 +56,6 @@ const loadBalancerWidth = 16 ...@@ -53,8 +56,6 @@ const loadBalancerWidth = 16
// NOTE: When adding a new resource type here, please update the list // NOTE: When adding a new resource type here, please update the list
// pkg/kubectl/cmd/get.go to reflect the new resource type. // pkg/kubectl/cmd/get.go to reflect the new resource type.
var ( var (
podColumns = []string{"NAME", "READY", "STATUS", "RESTARTS", "AGE"}
podWideColumns = []string{"IP", "NODE"}
podTemplateColumns = []string{"TEMPLATE", "CONTAINER(S)", "IMAGE(S)", "PODLABELS"} podTemplateColumns = []string{"TEMPLATE", "CONTAINER(S)", "IMAGE(S)", "PODLABELS"}
podDisruptionBudgetColumns = []string{"NAME", "MIN-AVAILABLE", "MAX-UNAVAILABLE", "ALLOWED-DISRUPTIONS", "AGE"} podDisruptionBudgetColumns = []string{"NAME", "MIN-AVAILABLE", "MAX-UNAVAILABLE", "ALLOWED-DISRUPTIONS", "AGE"}
replicationControllerColumns = []string{"NAME", "DESIRED", "CURRENT", "READY", "AGE"} replicationControllerColumns = []string{"NAME", "DESIRED", "CURRENT", "READY", "AGE"}
...@@ -105,27 +106,21 @@ var ( ...@@ -105,27 +106,21 @@ var (
podPresetColumns = []string{"NAME", "AGE"} podPresetColumns = []string{"NAME", "AGE"}
) )
func printPod(pod *api.Pod, w io.Writer, options printers.PrintOptions) error {
if err := printPodBase(pod, w, options); err != nil {
return err
}
return nil
}
func printPodList(podList *api.PodList, w io.Writer, options printers.PrintOptions) error {
for _, pod := range podList.Items {
if err := printPodBase(&pod, w, options); err != nil {
return err
}
}
return nil
}
// AddHandlers adds print handlers for default Kubernetes types dealing with internal versions. // AddHandlers adds print handlers for default Kubernetes types dealing with internal versions.
func AddHandlers(h *printers.HumanReadablePrinter) { // TODO: handle errors from Handler
h.Handler(podColumns, podWideColumns, printPodList) func AddHandlers(h printers.PrintHandler) {
h.Handler(podColumns, podWideColumns, printPod) podColumnDefinitions := []metav1alpha1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
{Name: "Ready", Type: "string", Description: "The aggregate readiness state of this pod for accepting traffic."},
{Name: "Status", Type: "string", Description: "The aggregate status of the containers in this pod."},
{Name: "Restarts", Type: "integer", Description: "The number of times the containers in this pod have been restarted."},
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
{Name: "IP", Type: "string", Priority: 1, Description: apiv1.PodStatus{}.SwaggerDoc()["podIP"]},
{Name: "Node", Type: "string", Priority: 1, Description: apiv1.PodSpec{}.SwaggerDoc()["nodeName"]},
}
h.TableHandler(podColumnDefinitions, printPodList)
h.TableHandler(podColumnDefinitions, printPod)
h.Handler(podTemplateColumns, nil, printPodTemplate) h.Handler(podTemplateColumns, nil, printPodTemplate)
h.Handler(podTemplateColumns, nil, printPodTemplateList) h.Handler(podTemplateColumns, nil, printPodTemplateList)
h.Handler(podDisruptionBudgetColumns, nil, printPodDisruptionBudget) h.Handler(podDisruptionBudgetColumns, nil, printPodDisruptionBudget)
...@@ -247,10 +242,24 @@ func translateTimestamp(timestamp metav1.Time) string { ...@@ -247,10 +242,24 @@ func translateTimestamp(timestamp metav1.Time) string {
return printers.ShortHumanDuration(time.Now().Sub(timestamp.Time)) return printers.ShortHumanDuration(time.Now().Sub(timestamp.Time))
} }
func printPodBase(pod *api.Pod, w io.Writer, options printers.PrintOptions) error { var (
name := printers.FormatResourceName(options.Kind, pod.Name, options.WithKind) podSuccessConditions = []metav1alpha1.TableRowCondition{{Type: metav1alpha1.RowCompleted, Status: metav1alpha1.ConditionTrue, Reason: string(api.PodSucceeded), Message: "The pod has completed successfully."}}
namespace := pod.Namespace podFailedConditions = []metav1alpha1.TableRowCondition{{Type: metav1alpha1.RowCompleted, Status: metav1alpha1.ConditionTrue, Reason: string(api.PodFailed), Message: "The pod failed."}}
)
func printPodList(podList *api.PodList, options printers.PrintOptions) ([]metav1alpha1.TableRow, error) {
rows := make([]metav1alpha1.TableRow, 0, len(podList.Items))
for i := range podList.Items {
r, err := printPod(&podList.Items[i], options)
if err != nil {
return nil, err
}
rows = append(rows, r...)
}
return rows, nil
}
func printPod(pod *api.Pod, options printers.PrintOptions) ([]metav1alpha1.TableRow, error) {
restarts := 0 restarts := 0
totalContainers := len(pod.Spec.Containers) totalContainers := len(pod.Spec.Containers)
readyContainers := 0 readyContainers := 0
...@@ -260,6 +269,17 @@ func printPodBase(pod *api.Pod, w io.Writer, options printers.PrintOptions) erro ...@@ -260,6 +269,17 @@ func printPodBase(pod *api.Pod, w io.Writer, options printers.PrintOptions) erro
reason = pod.Status.Reason reason = pod.Status.Reason
} }
row := metav1alpha1.TableRow{
Object: runtime.RawExtension{Object: pod},
}
switch pod.Status.Phase {
case api.PodSucceeded:
row.Conditions = podSuccessConditions
case api.PodFailed:
row.Conditions = podFailedConditions
}
initializing := false initializing := false
for i := range pod.Status.InitContainerStatuses { for i := range pod.Status.InitContainerStatuses {
container := pod.Status.InitContainerStatuses[i] container := pod.Status.InitContainerStatuses[i]
...@@ -316,21 +336,7 @@ func printPodBase(pod *api.Pod, w io.Writer, options printers.PrintOptions) erro ...@@ -316,21 +336,7 @@ func printPodBase(pod *api.Pod, w io.Writer, options printers.PrintOptions) erro
reason = "Terminating" reason = "Terminating"
} }
if options.WithNamespace { row.Cells = append(row.Cells, pod.Name, fmt.Sprintf("%d/%d", readyContainers, totalContainers), reason, restarts, translateTimestamp(pod.CreationTimestamp))
if _, err := fmt.Fprintf(w, "%s\t", namespace); err != nil {
return err
}
}
if _, err := fmt.Fprintf(w, "%s\t%d/%d\t%s\t%d\t%s",
name,
readyContainers,
totalContainers,
reason,
restarts,
translateTimestamp(pod.CreationTimestamp),
); err != nil {
return err
}
if options.Wide { if options.Wide {
nodeName := pod.Spec.NodeName nodeName := pod.Spec.NodeName
...@@ -341,22 +347,10 @@ func printPodBase(pod *api.Pod, w io.Writer, options printers.PrintOptions) erro ...@@ -341,22 +347,10 @@ func printPodBase(pod *api.Pod, w io.Writer, options printers.PrintOptions) erro
if nodeName == "" { if nodeName == "" {
nodeName = "<none>" nodeName = "<none>"
} }
if _, err := fmt.Fprintf(w, "\t%s\t%s", row.Cells = append(row.Cells, podIP, nodeName)
podIP,
nodeName,
); err != nil {
return err
}
} }
if _, err := fmt.Fprint(w, printers.AppendLabels(pod.Labels, options.ColumnLabels)); err != nil { return []metav1alpha1.TableRow{row}, nil
return err
}
if _, err := fmt.Fprint(w, printers.AppendAllLabels(options.ShowLabels, pod.Labels)); err != nil {
return err
}
return nil
} }
func printPodTemplate(pod *api.PodTemplate, w io.Writer, options printers.PrintOptions) error { func printPodTemplate(pod *api.PodTemplate, w io.Writer, options printers.PrintOptions) error {
......
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["storage.go"],
tags = ["automanaged"],
deps = [
"//pkg/printers:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package storage
import (
metav1alpha1 "k8s.io/apimachinery/pkg/apis/meta/v1alpha1"
"k8s.io/apimachinery/pkg/runtime"
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/kubernetes/pkg/printers"
)
type TableConvertor struct {
printers.TablePrinter
}
func (c TableConvertor) ConvertToTable(ctx genericapirequest.Context, obj runtime.Object, tableOptions runtime.Object) (*metav1alpha1.Table, error) {
return c.TablePrinter.PrintTable(obj, printers.PrintOptions{Wide: true})
}
...@@ -15,12 +15,14 @@ go_test( ...@@ -15,12 +15,14 @@ go_test(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/registry/registrytest:go_default_library", "//pkg/registry/registrytest:go_default_library",
"//pkg/securitycontext:go_default_library", "//pkg/securitycontext:go_default_library",
"//vendor/golang.org/x/net/context:go_default_library", "//vendor/golang.org/x/net/context:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
...@@ -49,6 +51,9 @@ go_library( ...@@ -49,6 +51,9 @@ go_library(
"//pkg/client/clientset_generated/internalclientset/typed/policy/internalversion:go_default_library", "//pkg/client/clientset_generated/internalclientset/typed/policy/internalversion:go_default_library",
"//pkg/client/retry:go_default_library", "//pkg/client/retry:go_default_library",
"//pkg/kubelet/client:go_default_library", "//pkg/kubelet/client:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/printers/internalversion:go_default_library",
"//pkg/printers/storage:go_default_library",
"//pkg/registry/cachesize:go_default_library", "//pkg/registry/cachesize:go_default_library",
"//pkg/registry/core/pod:go_default_library", "//pkg/registry/core/pod:go_default_library",
"//pkg/registry/core/pod/rest:go_default_library", "//pkg/registry/core/pod/rest:go_default_library",
......
...@@ -35,6 +35,9 @@ import ( ...@@ -35,6 +35,9 @@ import (
"k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/api/validation"
policyclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/policy/internalversion" policyclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/policy/internalversion"
"k8s.io/kubernetes/pkg/kubelet/client" "k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/printers"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
printerstorage "k8s.io/kubernetes/pkg/printers/storage"
"k8s.io/kubernetes/pkg/registry/cachesize" "k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/core/pod" "k8s.io/kubernetes/pkg/registry/core/pod"
podrest "k8s.io/kubernetes/pkg/registry/core/pod/rest" podrest "k8s.io/kubernetes/pkg/registry/core/pod/rest"
...@@ -61,6 +64,7 @@ type REST struct { ...@@ -61,6 +64,7 @@ type REST struct {
// NewStorage returns a RESTStorage object that will work against pods. // NewStorage returns a RESTStorage object that will work against pods.
func NewStorage(optsGetter generic.RESTOptionsGetter, k client.ConnectionInfoGetter, proxyTransport http.RoundTripper, podDisruptionBudgetClient policyclient.PodDisruptionBudgetsGetter) PodStorage { func NewStorage(optsGetter generic.RESTOptionsGetter, k client.ConnectionInfoGetter, proxyTransport http.RoundTripper, podDisruptionBudgetClient policyclient.PodDisruptionBudgetsGetter) PodStorage {
store := &genericregistry.Store{ store := &genericregistry.Store{
Copier: api.Scheme, Copier: api.Scheme,
NewFunc: func() runtime.Object { return &api.Pod{} }, NewFunc: func() runtime.Object { return &api.Pod{} },
...@@ -73,6 +77,8 @@ func NewStorage(optsGetter generic.RESTOptionsGetter, k client.ConnectionInfoGet ...@@ -73,6 +77,8 @@ func NewStorage(optsGetter generic.RESTOptionsGetter, k client.ConnectionInfoGet
UpdateStrategy: pod.Strategy, UpdateStrategy: pod.Strategy,
DeleteStrategy: pod.Strategy, DeleteStrategy: pod.Strategy,
ReturnDeletedObject: true, ReturnDeletedObject: true,
TableConvertor: printerstorage.TableConvertor{TablePrinter: printers.NewTablePrinter().With(printersinternal.AddHandlers)},
} }
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: pod.GetAttrs, TriggerFunc: pod.NodeNameTriggerFunc} options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: pod.GetAttrs, TriggerFunc: pod.NodeNameTriggerFunc}
if err := store.CompleteWithOptions(options); err != nil { if err := store.CompleteWithOptions(options); err != nil {
......
...@@ -19,11 +19,13 @@ package storage ...@@ -19,11 +19,13 @@ package storage
import ( import (
"strings" "strings"
"testing" "testing"
"time"
"golang.org/x/net/context" "golang.org/x/net/context"
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1alpha1 "k8s.io/apimachinery/pkg/apis/meta/v1alpha1"
"k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
...@@ -35,6 +37,7 @@ import ( ...@@ -35,6 +37,7 @@ import (
storeerr "k8s.io/apiserver/pkg/storage/errors" storeerr "k8s.io/apiserver/pkg/storage/errors"
etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing" etcdtesting "k8s.io/apiserver/pkg/storage/etcd/testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/securitycontext"
) )
...@@ -396,6 +399,88 @@ func TestWatch(t *testing.T) { ...@@ -396,6 +399,88 @@ func TestWatch(t *testing.T) {
) )
} }
func TestConvertToTableList(t *testing.T) {
storage, _, _, server := newStorage(t)
defer server.Terminate(t)
defer storage.Store.DestroyFunc()
ctx := genericapirequest.NewDefaultContext()
columns := []metav1alpha1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
{Name: "Ready", Type: "string", Description: "The aggregate readiness state of this pod for accepting traffic."},
{Name: "Status", Type: "string", Description: "The aggregate status of the containers in this pod."},
{Name: "Restarts", Type: "integer", Description: "The number of times the containers in this pod have been restarted."},
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
{Name: "IP", Type: "string", Priority: 1, Description: v1.PodStatus{}.SwaggerDoc()["podIP"]},
{Name: "Node", Type: "string", Priority: 1, Description: v1.PodSpec{}.SwaggerDoc()["nodeName"]},
}
pod1 := &api.Pod{
ObjectMeta: metav1.ObjectMeta{Namespace: "test", Name: "foo", CreationTimestamp: metav1.NewTime(time.Now().Add(-370 * 24 * time.Hour))},
Spec: api.PodSpec{
Containers: []api.Container{
{Name: "ctr1"},
{Name: "ctr2", Ports: []api.ContainerPort{{ContainerPort: 9376}}},
},
NodeName: "test-node",
},
Status: api.PodStatus{
PodIP: "10.1.2.3",
Phase: api.PodPending,
ContainerStatuses: []api.ContainerStatus{
{Name: "ctr1", State: api.ContainerState{Running: &api.ContainerStateRunning{}}, RestartCount: 10, Ready: true},
{Name: "ctr2", State: api.ContainerState{Waiting: &api.ContainerStateWaiting{}}, RestartCount: 0},
},
},
}
testCases := []struct {
in runtime.Object
out *metav1alpha1.Table
err bool
}{
{
in: nil,
err: true,
},
{
in: &api.Pod{},
out: &metav1alpha1.Table{
ColumnDefinitions: columns,
Rows: []metav1alpha1.TableRow{
{Cells: []interface{}{"", "0/0", "", 0, "<unknown>", "<none>", "<none>"}, Object: runtime.RawExtension{Object: &api.Pod{}}},
},
},
},
{
in: pod1,
out: &metav1alpha1.Table{
ColumnDefinitions: columns,
Rows: []metav1alpha1.TableRow{
{Cells: []interface{}{"foo", "1/2", "Pending", 10, "1y", "10.1.2.3", "test-node"}, Object: runtime.RawExtension{Object: pod1}},
},
},
},
{
in: &api.PodList{},
out: &metav1alpha1.Table{ColumnDefinitions: columns},
},
}
for i, test := range testCases {
out, err := storage.ConvertToTable(ctx, test.in, nil)
if err != nil {
if test.err {
continue
}
t.Errorf("%d: error: %v", i, err)
continue
}
if !apiequality.Semantic.DeepEqual(test.out, out) {
t.Errorf("%d: mismatch: %s", i, diff.ObjectReflectDiff(test.out, out))
}
}
}
func TestEtcdCreate(t *testing.T) { func TestEtcdCreate(t *testing.T) {
storage, bindingStorage, _, server := newStorage(t) storage, bindingStorage, _, server := newStorage(t)
defer server.Terminate(t) defer server.Terminate(t)
......
...@@ -11,6 +11,7 @@ load( ...@@ -11,6 +11,7 @@ load(
go_test( go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"meta_test.go",
"multirestmapper_test.go", "multirestmapper_test.go",
"priority_test.go", "priority_test.go",
"restmapper_test.go", "restmapper_test.go",
...@@ -18,8 +19,12 @@ go_test( ...@@ -18,8 +19,12 @@ go_test(
library = ":go_default_library", library = ":go_default_library",
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//vendor/github.com/google/gofuzz:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
], ],
) )
......
...@@ -114,6 +114,7 @@ func AsPartialObjectMetadata(m metav1.Object) *metav1alpha1.PartialObjectMetadat ...@@ -114,6 +114,7 @@ func AsPartialObjectMetadata(m metav1.Object) *metav1alpha1.PartialObjectMetadat
OwnerReferences: m.GetOwnerReferences(), OwnerReferences: m.GetOwnerReferences(),
Finalizers: m.GetFinalizers(), Finalizers: m.GetFinalizers(),
ClusterName: m.GetClusterName(), ClusterName: m.GetClusterName(),
Initializers: m.GetInitializers(),
}, },
} }
} }
......
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package meta
import (
"math/rand"
"reflect"
"testing"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1alpha1 "k8s.io/apimachinery/pkg/apis/meta/v1alpha1"
"k8s.io/apimachinery/pkg/util/diff"
fuzz "github.com/google/gofuzz"
)
func TestAsPartialObjectMetadata(t *testing.T) {
f := fuzz.New().NilChance(.5).NumElements(0, 1).RandSource(rand.NewSource(1))
for i := 0; i < 100; i++ {
m := &metav1.ObjectMeta{}
f.Fuzz(m)
partial := AsPartialObjectMetadata(m)
if !reflect.DeepEqual(&partial.ObjectMeta, m) {
t.Fatalf("incomplete partial object metadata: %s", diff.ObjectReflectDiff(&partial.ObjectMeta, m))
}
}
for i := 0; i < 100; i++ {
m := &metav1alpha1.PartialObjectMetadata{}
f.Fuzz(&m.ObjectMeta)
partial := AsPartialObjectMetadata(m)
if !reflect.DeepEqual(&partial.ObjectMeta, &m.ObjectMeta) {
t.Fatalf("incomplete partial object metadata: %s", diff.ObjectReflectDiff(&partial.ObjectMeta, &m.ObjectMeta))
}
}
}
...@@ -149,6 +149,9 @@ func (meta *ObjectMeta) GetFinalizers() []string { return m ...@@ -149,6 +149,9 @@ func (meta *ObjectMeta) GetFinalizers() []string { return m
func (meta *ObjectMeta) SetFinalizers(finalizers []string) { meta.Finalizers = finalizers } func (meta *ObjectMeta) SetFinalizers(finalizers []string) { meta.Finalizers = finalizers }
func (meta *ObjectMeta) GetOwnerReferences() []OwnerReference { func (meta *ObjectMeta) GetOwnerReferences() []OwnerReference {
if meta.OwnerReferences == nil {
return nil
}
ret := make([]OwnerReference, len(meta.OwnerReferences)) ret := make([]OwnerReference, len(meta.OwnerReferences))
for i := 0; i < len(meta.OwnerReferences); i++ { for i := 0; i < len(meta.OwnerReferences); i++ {
ret[i].Kind = meta.OwnerReferences[i].Kind ret[i].Kind = meta.OwnerReferences[i].Kind
...@@ -168,6 +171,10 @@ func (meta *ObjectMeta) GetOwnerReferences() []OwnerReference { ...@@ -168,6 +171,10 @@ func (meta *ObjectMeta) GetOwnerReferences() []OwnerReference {
} }
func (meta *ObjectMeta) SetOwnerReferences(references []OwnerReference) { func (meta *ObjectMeta) SetOwnerReferences(references []OwnerReference) {
if references == nil {
meta.OwnerReferences = nil
return
}
newReferences := make([]OwnerReference, len(references)) newReferences := make([]OwnerReference, len(references))
for i := 0; i < len(references); i++ { for i := 0; i < len(references); i++ {
newReferences[i].Kind = references[i].Kind newReferences[i].Kind = references[i].Kind
......
...@@ -34,7 +34,7 @@ import ( ...@@ -34,7 +34,7 @@ import (
// transformResponseObject takes an object loaded from storage and performs any necessary transformations. // transformResponseObject takes an object loaded from storage and performs any necessary transformations.
// Will write the complete response object. // Will write the complete response object.
func transformResponseObject(ctx request.Context, scope RequestScope, req *http.Request, w http.ResponseWriter, statusCode int, result runtime.Object) { func transformResponseObject(ctx request.Context, scope RequestScope, req *http.Request, w http.ResponseWriter, statusCode int, result runtime.Object) {
// TODO: use returned serializer // TODO: fetch the media type much earlier in request processing and pass it into this method.
mediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope) mediaType, _, err := negotiation.NegotiateOutputMediaType(req, scope.Serializer, &scope)
if err != nil { if err != nil {
status := responsewriters.ErrorToAPIStatus(err) status := responsewriters.ErrorToAPIStatus(err)
...@@ -169,7 +169,7 @@ func transformResponseObject(ctx request.Context, scope RequestScope, req *http. ...@@ -169,7 +169,7 @@ func transformResponseObject(ctx request.Context, scope RequestScope, req *http.
} }
} }
responsewriters.WriteObject(statusCode, scope.Kind.GroupVersion(), scope.Serializer, result, w, req) responsewriters.WriteObject(ctx, statusCode, scope.Kind.GroupVersion(), scope.Serializer, result, w, req)
} }
// errNotAcceptable indicates Accept negotiation has failed // errNotAcceptable indicates Accept negotiation has failed
......
...@@ -62,6 +62,7 @@ go_library( ...@@ -62,6 +62,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/api/validation/path:go_default_library", "//vendor/k8s.io/apimachinery/pkg/api/validation/path:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
......
...@@ -28,6 +28,7 @@ import ( ...@@ -28,6 +28,7 @@ import (
"k8s.io/apimachinery/pkg/api/validation/path" "k8s.io/apimachinery/pkg/api/validation/path"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1alpha1 "k8s.io/apimachinery/pkg/apis/meta/v1alpha1"
"k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
...@@ -155,6 +156,9 @@ type Store struct { ...@@ -155,6 +156,9 @@ type Store struct {
// ExportStrategy implements resource-specific behavior during export, // ExportStrategy implements resource-specific behavior during export,
// optional. Exported objects are not decorated. // optional. Exported objects are not decorated.
ExportStrategy rest.RESTExportStrategy ExportStrategy rest.RESTExportStrategy
// TableConvertor is an optional interface for transforming items or lists
// of items into tabular output. If unset, the default will be used.
TableConvertor rest.TableConvertor
// Storage is the interface for the underlying storage for the resource. // Storage is the interface for the underlying storage for the resource.
Storage storage.Interface Storage storage.Interface
...@@ -169,6 +173,7 @@ type Store struct { ...@@ -169,6 +173,7 @@ type Store struct {
// Note: the rest.StandardStorage interface aggregates the common REST verbs // Note: the rest.StandardStorage interface aggregates the common REST verbs
var _ rest.StandardStorage = &Store{} var _ rest.StandardStorage = &Store{}
var _ rest.Exporter = &Store{} var _ rest.Exporter = &Store{}
var _ rest.TableConvertor = &Store{}
const OptimisticLockErrorMsg = "the object has been modified; please apply your changes to the latest version and try again" const OptimisticLockErrorMsg = "the object has been modified; please apply your changes to the latest version and try again"
...@@ -1230,3 +1235,10 @@ func (e *Store) CompleteWithOptions(options *generic.StoreOptions) error { ...@@ -1230,3 +1235,10 @@ func (e *Store) CompleteWithOptions(options *generic.StoreOptions) error {
return nil return nil
} }
func (e *Store) ConvertToTable(ctx genericapirequest.Context, object runtime.Object, tableOptions runtime.Object) (*metav1alpha1.Table, error) {
if e.TableConvertor != nil {
return e.TableConvertor.ConvertToTable(ctx, object, tableOptions)
}
return rest.DefaultTableConvertor.ConvertToTable(ctx, object, tableOptions)
}
...@@ -31,6 +31,7 @@ go_library( ...@@ -31,6 +31,7 @@ go_library(
"export.go", "export.go",
"meta.go", "meta.go",
"rest.go", "rest.go",
"table.go",
"update.go", "update.go",
], ],
tags = ["automanaged"], tags = ["automanaged"],
...@@ -42,6 +43,7 @@ go_library( ...@@ -42,6 +43,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library", "//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
......
...@@ -118,7 +118,7 @@ type GetterWithOptions interface { ...@@ -118,7 +118,7 @@ type GetterWithOptions interface {
} }
type TableConvertor interface { type TableConvertor interface {
ConvertToTableList(ctx genericapirequest.Context, object runtime.Object, tableOptions runtime.Object) (*metav1alpha1.TableList, error) ConvertToTable(ctx genericapirequest.Context, object runtime.Object, tableOptions runtime.Object) (*metav1alpha1.Table, error)
} }
// Deleter is an object that can delete a named RESTful resource. // Deleter is an object that can delete a named RESTful resource.
......
...@@ -32,15 +32,15 @@ type defaultTableConvertor struct{} ...@@ -32,15 +32,15 @@ type defaultTableConvertor struct{}
var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc() var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
func (defaultTableConvertor) ConvertToTableList(ctx genericapirequest.Context, object runtime.Object, tableOptions runtime.Object) (*metav1alpha1.TableList, error) { func (defaultTableConvertor) ConvertToTable(ctx genericapirequest.Context, object runtime.Object, tableOptions runtime.Object) (*metav1alpha1.Table, error) {
var table metav1alpha1.TableList var table metav1alpha1.Table
fn := func(obj runtime.Object) error { fn := func(obj runtime.Object) error {
m, err := meta.Accessor(obj) m, err := meta.Accessor(obj)
if err != nil { if err != nil {
// TODO: skip objects we don't recognize // TODO: skip objects we don't recognize
return nil return nil
} }
table.Items = append(table.Items, metav1alpha1.TableListItem{ table.Rows = append(table.Rows, metav1alpha1.TableRow{
Cells: []interface{}{m.GetClusterName(), m.GetNamespace(), m.GetName(), m.GetCreationTimestamp().Time.UTC().Format(time.RFC3339)}, Cells: []interface{}{m.GetClusterName(), m.GetNamespace(), m.GetName(), m.GetCreationTimestamp().Time.UTC().Format(time.RFC3339)},
Object: runtime.RawExtension{Object: obj}, Object: runtime.RawExtension{Object: obj},
}) })
...@@ -56,7 +56,7 @@ func (defaultTableConvertor) ConvertToTableList(ctx genericapirequest.Context, o ...@@ -56,7 +56,7 @@ func (defaultTableConvertor) ConvertToTableList(ctx genericapirequest.Context, o
return nil, err return nil, err
} }
} }
table.Headers = []metav1alpha1.TableListHeader{ table.ColumnDefinitions = []metav1alpha1.TableColumnDefinition{
{Name: "Cluster Name", Type: "string", Description: swaggerMetadataDescriptions["clusterName"]}, {Name: "Cluster Name", Type: "string", Description: swaggerMetadataDescriptions["clusterName"]},
{Name: "Namespace", Type: "string", Description: swaggerMetadataDescriptions["namespace"]}, {Name: "Namespace", Type: "string", Description: swaggerMetadataDescriptions["namespace"]},
{Name: "Name", Type: "string", Description: swaggerMetadataDescriptions["name"]}, {Name: "Name", Type: "string", Description: swaggerMetadataDescriptions["name"]},
...@@ -71,8 +71,8 @@ func (defaultTableConvertor) ConvertToTableList(ctx genericapirequest.Context, o ...@@ -71,8 +71,8 @@ func (defaultTableConvertor) ConvertToTableList(ctx genericapirequest.Context, o
return &table, nil return &table, nil
} }
func trimColumn(column int, table *metav1alpha1.TableList) bool { func trimColumn(column int, table *metav1alpha1.Table) bool {
for _, item := range table.Items { for _, item := range table.Rows {
switch t := item.Cells[column].(type) { switch t := item.Cells[column].(type) {
case string: case string:
if len(t) > 0 { if len(t) > 0 {
...@@ -85,22 +85,22 @@ func trimColumn(column int, table *metav1alpha1.TableList) bool { ...@@ -85,22 +85,22 @@ func trimColumn(column int, table *metav1alpha1.TableList) bool {
} }
} }
if column == 0 { if column == 0 {
table.Headers = table.Headers[1:] table.ColumnDefinitions = table.ColumnDefinitions[1:]
} else { } else {
for j := column; j < len(table.Headers); j++ { for j := column; j < len(table.ColumnDefinitions); j++ {
table.Headers[j] = table.Headers[j+1] table.ColumnDefinitions[j] = table.ColumnDefinitions[j+1]
} }
} }
for i := range table.Items { for i := range table.Rows {
cells := table.Items[i].Cells cells := table.Rows[i].Cells
if column == 0 { if column == 0 {
table.Items[i].Cells = cells[1:] table.Rows[i].Cells = cells[1:]
continue continue
} }
for j := column; j < len(cells); j++ { for j := column; j < len(cells); j++ {
cells[j] = cells[j+1] cells[j] = cells[j+1]
} }
table.Items[i].Cells = cells[:len(cells)-1] table.Rows[i].Cells = cells[:len(cells)-1]
} }
return true return true
} }
...@@ -331,6 +331,10 @@ ...@@ -331,6 +331,10 @@
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}, },
{ {
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1alpha1",
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/conversion", "ImportPath": "k8s.io/apimachinery/pkg/conversion",
"Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "Rev": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment