Refactor printers to separate typed printers from generic code

parent 6d1c7308
......@@ -13,7 +13,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/printers:go_default_library",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/util/validation/field",
......
......@@ -30,7 +30,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/printers"
)
// Based on: https://github.com/openshift/origin/blob/master/pkg/api/compatibility_test.go
......@@ -94,7 +94,7 @@ func TestCompatibility(
}
if hasError {
printer := new(kubectl.JSONPrinter)
printer := &printers.JSONPrinter{}
printer.PrintObj(obj, os.Stdout)
t.Logf("2: Encoded value: %#v", string(output))
}
......
......@@ -63,6 +63,7 @@ go_test(
tags = ["automanaged"],
deps = [
"//pkg/api:go_default_library",
"//pkg/api/install:go_default_library",
"//pkg/api/testing/compat:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/api/validation:go_default_library",
......
......@@ -25,6 +25,8 @@ import (
"k8s.io/kubernetes/pkg/api/testing/compat"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/validation"
_ "k8s.io/kubernetes/pkg/api/install"
)
func TestCompatibility_v1_PodSecurityContext(t *testing.T) {
......
/*
Copyright 2014 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 printers
import (
"fmt"
"time"
)
func ShortHumanDuration(d time.Duration) string {
// Allow deviation no more than 2 seconds(excluded) to tolerate machine time
// inconsistence, it can be considered as almost now.
if seconds := int(d.Seconds()); seconds < -1 {
return fmt.Sprintf("<invalid>")
} else if seconds < 0 {
return fmt.Sprintf("0s")
} else if seconds < 60 {
return fmt.Sprintf("%ds", seconds)
} else if minutes := int(d.Minutes()); minutes < 60 {
return fmt.Sprintf("%dm", minutes)
} else if hours := int(d.Hours()); hours < 24 {
return fmt.Sprintf("%dh", hours)
} else if hours < 24*364 {
return fmt.Sprintf("%dd", hours/24)
}
return fmt.Sprintf("%dy", int(d.Hours()/24/365))
}
......@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package kubectl
package printers
import (
"bufio"
......@@ -41,14 +41,14 @@ const (
var jsonRegexp = regexp.MustCompile("^\\{\\.?([^{}]+)\\}$|^\\.?([^{}]+)$")
// MassageJSONPath attempts to be flexible with JSONPath expressions, it accepts:
// RelaxedJSONPathExpression attempts to be flexible with JSONPath expressions, it accepts:
// * metadata.name (no leading '.' or curly brances '{...}'
// * {metadata.name} (no leading '.')
// * .metadata.name (no curly braces '{...}')
// * {.metadata.name} (complete expression)
// And transforms them all into a valid jsonpat expression:
// And transforms them all into a valid jsonpath expression:
// {.metadata.name}
func massageJSONPath(pathExpression string) (string, error) {
func RelaxedJSONPathExpression(pathExpression string) (string, error) {
if len(pathExpression) == 0 {
return pathExpression, nil
}
......@@ -84,7 +84,7 @@ func NewCustomColumnsPrinterFromSpec(spec string, decoder runtime.Decoder, noHea
if len(colSpec) != 2 {
return nil, fmt.Errorf("unexpected custom-columns spec: %s, expected <header>:<json-path-expr>", parts[ix])
}
spec, err := massageJSONPath(colSpec[1])
spec, err := RelaxedJSONPathExpression(colSpec[1])
if err != nil {
return nil, err
}
......@@ -126,7 +126,7 @@ func NewCustomColumnsPrinterFromTemplate(templateReader io.Reader, decoder runti
columns := make([]Column, len(headers))
for ix := range headers {
spec, err := massageJSONPath(specs[ix])
spec, err := RelaxedJSONPathExpression(specs[ix])
if err != nil {
return nil, err
}
......
......@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package kubectl
package printers_test
import (
"bytes"
......@@ -26,6 +26,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/printers"
)
func TestMassageJSONPath(t *testing.T) {
......@@ -45,7 +46,7 @@ func TestMassageJSONPath(t *testing.T) {
{input: "{{foo.bar}", expectErr: true},
}
for _, test := range tests {
output, err := massageJSONPath(test.input)
output, err := printers.RelaxedJSONPathExpression(test.input)
if err != nil && !test.expectErr {
t.Errorf("unexpected error: %v", err)
continue
......@@ -65,7 +66,7 @@ func TestMassageJSONPath(t *testing.T) {
func TestNewColumnPrinterFromSpec(t *testing.T) {
tests := []struct {
spec string
expectedColumns []Column
expectedColumns []printers.Column
expectErr bool
name string
noHeaders bool
......@@ -93,7 +94,7 @@ func TestNewColumnPrinterFromSpec(t *testing.T) {
{
spec: "NAME:metadata.name,API_VERSION:apiVersion",
name: "ok",
expectedColumns: []Column{
expectedColumns: []printers.Column{
{
Header: "NAME",
FieldSpec: "{.metadata.name}",
......@@ -111,7 +112,7 @@ func TestNewColumnPrinterFromSpec(t *testing.T) {
},
}
for _, test := range tests {
printer, err := NewCustomColumnsPrinterFromSpec(test.spec, api.Codecs.UniversalDecoder(), test.noHeaders)
printer, err := printers.NewCustomColumnsPrinterFromSpec(test.spec, api.Codecs.UniversalDecoder(), test.noHeaders)
if test.expectErr {
if err == nil {
t.Errorf("[%s] unexpected non-error", test.name)
......@@ -141,6 +142,15 @@ func TestNewColumnPrinterFromSpec(t *testing.T) {
}
}
func contains(arr []string, s string) bool {
for i := range arr {
if arr[i] == s {
return true
}
}
return false
}
const exampleTemplateOne = `NAME API_VERSION
{metadata.name} {apiVersion}`
......@@ -150,7 +160,7 @@ const exampleTemplateTwo = `NAME API_VERSION
func TestNewColumnPrinterFromTemplate(t *testing.T) {
tests := []struct {
spec string
expectedColumns []Column
expectedColumns []printers.Column
expectErr bool
name string
}{
......@@ -177,7 +187,7 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) {
{
spec: exampleTemplateOne,
name: "ok",
expectedColumns: []Column{
expectedColumns: []printers.Column{
{
Header: "NAME",
FieldSpec: "{.metadata.name}",
......@@ -191,7 +201,7 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) {
{
spec: exampleTemplateTwo,
name: "ok-2",
expectedColumns: []Column{
expectedColumns: []printers.Column{
{
Header: "NAME",
FieldSpec: "{.metadata.name}",
......@@ -205,7 +215,7 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) {
}
for _, test := range tests {
reader := bytes.NewBufferString(test.spec)
printer, err := NewCustomColumnsPrinterFromTemplate(reader, api.Codecs.UniversalDecoder())
printer, err := printers.NewCustomColumnsPrinterFromTemplate(reader, api.Codecs.UniversalDecoder())
if test.expectErr {
if err == nil {
t.Errorf("[%s] unexpected non-error", test.name)
......@@ -226,12 +236,12 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) {
func TestColumnPrint(t *testing.T) {
tests := []struct {
columns []Column
columns []printers.Column
obj runtime.Object
expectedOutput string
}{
{
columns: []Column{
columns: []printers.Column{
{
Header: "NAME",
FieldSpec: "{.metadata.name}",
......@@ -243,7 +253,7 @@ foo
`,
},
{
columns: []Column{
columns: []printers.Column{
{
Header: "NAME",
FieldSpec: "{.metadata.name}",
......@@ -261,7 +271,7 @@ bar
`,
},
{
columns: []Column{
columns: []printers.Column{
{
Header: "NAME",
FieldSpec: "{.metadata.name}",
......@@ -279,7 +289,7 @@ foo baz
}
for _, test := range tests {
printer := &CustomColumnsPrinter{
printer := &printers.CustomColumnsPrinter{
Columns: test.columns,
Decoder: api.Codecs.UniversalDecoder(),
}
......
......@@ -17,14 +17,23 @@ limitations under the License.
package printers
import (
"bytes"
"fmt"
"io"
"reflect"
"strings"
"text/tabwriter"
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)
var withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print cluster name too.
type handlerEntry struct {
columns []string
columnsWithWide []string
......@@ -49,20 +58,9 @@ func NewHumanReadablePrinter(options PrintOptions) *HumanReadablePrinter {
handlerMap: make(map[reflect.Type]*handlerEntry),
options: options,
}
printer.addDefaultHandlers()
return printer
}
// formatResourceName receives a resource kind, name, and boolean specifying
// whether or not to update the current name to "kind/name"
func formatResourceName(kind, name string, withKind bool) string {
if !withKind || kind == "" {
return name
}
return kind + "/" + name
}
// GetResourceKind returns the type currently set for a resource
func (h *HumanReadablePrinter) GetResourceKind() string {
return h.options.Kind
......@@ -157,3 +155,175 @@ func (h *HumanReadablePrinter) printHeader(columnNames []string, w io.Writer) er
}
return nil
}
// PrintObj prints the obj in a human-friendly format according to the type of the obj.
func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) error {
// if output is a tabwriter (when it's called by kubectl get), we use it; create a new tabwriter otherwise
w, found := output.(*tabwriter.Writer)
if !found {
w = GetNewTabWriter(output)
defer w.Flush()
}
// 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.
//obj, _ = DecodeUnknownObject(obj)
t := reflect.TypeOf(obj)
if handler := h.handlerMap[t]; handler != nil {
if !h.options.NoHeaders && t != h.lastType {
headers := handler.columns
if h.options.Wide {
headers = append(headers, handler.columnsWithWide...)
}
headers = append(headers, formatLabelHeaders(h.options.ColumnLabels)...)
// LABELS is always the last column.
headers = append(headers, formatShowLabelsHeader(h.options.ShowLabels, t)...)
if h.options.WithNamespace {
headers = append(withNamespacePrefixColumns, headers...)
}
h.printHeader(headers, w)
h.lastType = t
}
args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(w), reflect.ValueOf(h.options)}
resultValue := handler.printFunc.Call(args)[0]
if resultValue.IsNil() {
return nil
}
return resultValue.Interface().(error)
}
if _, err := meta.Accessor(obj); err == nil {
if !h.options.NoHeaders && t != h.lastType {
headers := []string{"NAME", "KIND"}
headers = append(headers, formatLabelHeaders(h.options.ColumnLabels)...)
// LABELS is always the last column.
headers = append(headers, formatShowLabelsHeader(h.options.ShowLabels, t)...)
if h.options.WithNamespace {
headers = append(withNamespacePrefixColumns, headers...)
}
h.printHeader(headers, w)
h.lastType = t
}
// we don't recognize this type, but we can still attempt to print some reasonable information about.
unstructured, ok := obj.(runtime.Unstructured)
if !ok {
return fmt.Errorf("error: unknown type %#v", obj)
}
// if the error isn't nil, report the "I don't recognize this" error
if err := printUnstructured(unstructured, w, h.options); err != nil {
return err
}
return nil
}
// we failed all reasonable printing efforts, report failure
return fmt.Errorf("error: unknown type %#v", obj)
}
// TODO: this method assumes the meta/v1 server API, so should be refactored out of this package
func printUnstructured(unstructured runtime.Unstructured, w io.Writer, options PrintOptions) error {
metadata, err := meta.Accessor(unstructured)
if err != nil {
return err
}
if options.WithNamespace {
if _, err := fmt.Fprintf(w, "%s\t", metadata.GetNamespace()); err != nil {
return err
}
}
content := unstructured.UnstructuredContent()
kind := "<missing>"
if objKind, ok := content["kind"]; ok {
if str, ok := objKind.(string); ok {
kind = str
}
}
if objAPIVersion, ok := content["apiVersion"]; ok {
if str, ok := objAPIVersion.(string); ok {
version, err := schema.ParseGroupVersion(str)
if err != nil {
return err
}
kind = kind + "." + version.Version + "." + version.Group
}
}
name := formatResourceName(options.Kind, metadata.GetName(), options.WithKind)
if _, err := fmt.Fprintf(w, "%s\t%s", name, kind); err != nil {
return err
}
if _, err := fmt.Fprint(w, appendLabels(metadata.GetLabels(), options.ColumnLabels)); err != nil {
return err
}
if _, err := fmt.Fprint(w, appendAllLabels(options.ShowLabels, metadata.GetLabels())); err != nil {
return err
}
return nil
}
func formatLabelHeaders(columnLabels []string) []string {
formHead := make([]string, len(columnLabels))
for i, l := range columnLabels {
p := strings.Split(l, "/")
formHead[i] = strings.ToUpper((p[len(p)-1]))
}
return formHead
}
// headers for --show-labels=true
func formatShowLabelsHeader(showLabels bool, t reflect.Type) []string {
if showLabels {
// TODO: this is all sorts of hack, fix
if t.String() != "*api.ThirdPartyResource" && t.String() != "*api.ThirdPartyResourceList" {
return []string{"LABELS"}
}
}
return nil
}
// formatResourceName receives a resource kind, name, and boolean specifying
// whether or not to update the current name to "kind/name"
// TODO: dedup this with printers/internalversions
func formatResourceName(kind, name string, withKind bool) string {
if !withKind || kind == "" {
return name
}
return kind + "/" + name
}
// TODO: dedup this with printers/internalversions
func appendLabels(itemLabels map[string]string, columnLabels []string) string {
var buffer bytes.Buffer
for _, cl := range columnLabels {
buffer.WriteString(fmt.Sprint("\t"))
if il, ok := itemLabels[cl]; ok {
buffer.WriteString(fmt.Sprint(il))
} else {
buffer.WriteString("<none>")
}
}
return buffer.String()
}
// Append all labels to a single column. We need this even when show-labels flag* is
// false, since this adds newline delimiter to the end of each row.
// TODO: dedup this with printers/internalversions
func appendAllLabels(showLabels bool, itemLabels map[string]string) string {
var buffer bytes.Buffer
if showLabels {
buffer.WriteString(fmt.Sprint("\t"))
buffer.WriteString(labels.FormatLabels(itemLabels))
}
buffer.WriteString("\n")
return buffer.String()
}
......@@ -17,6 +17,7 @@ limitations under the License.
package printers
import (
"fmt"
"io"
"k8s.io/apimachinery/pkg/runtime"
......@@ -60,3 +61,36 @@ type PrintOptions struct {
Kind string
ColumnLabels []string
}
// Describer generates output for the named resource or an error
// if the output could not be generated. Implementers typically
// abstract the retrieval of the named object from a remote server.
type Describer interface {
Describe(namespace, name string, describerSettings DescriberSettings) (output string, err error)
}
// DescriberSettings holds display configuration for each object
// describer to control what is printed.
type DescriberSettings struct {
ShowEvents bool
}
// ObjectDescriber is an interface for displaying arbitrary objects with extra
// information. Use when an object is in hand (on disk, or already retrieved).
// Implementers may ignore the additional information passed on extra, or use it
// by default. ObjectDescribers may return ErrNoDescriber if no suitable describer
// is found.
type ObjectDescriber interface {
DescribeObject(object interface{}, extra ...interface{}) (output string, err error)
}
// ErrNoDescriber is a structured error indicating the provided object or objects
// cannot be described.
type ErrNoDescriber struct {
Types []string
}
// Error implements the error interface.
func (e ErrNoDescriber) Error() string {
return fmt.Sprintf("no describer has been defined for %v", e.Types)
}
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)
go_test(
name = "go_default_test",
srcs = [
"describe_test.go",
"printers_test.go",
"sorted_resource_name_list_test.go",
],
library = ":go_default_library",
tags = ["automanaged"],
deps = [
"//federation/apis/federation:go_default_library",
"//federation/client/clientset_generated/federation_internalclientset/fake:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/autoscaling:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//pkg/apis/policy:go_default_library",
"//pkg/apis/storage:go_default_library",
"//pkg/client/clientset_generated/clientset/fake:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
"//pkg/kubectl/testing:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/util:go_default_library",
"//vendor:github.com/ghodss/yaml",
"//vendor:k8s.io/apimachinery/pkg/api/equality",
"//vendor:k8s.io/apimachinery/pkg/api/resource",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
"//vendor:k8s.io/apimachinery/pkg/runtime",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/runtime/serializer/yaml",
"//vendor:k8s.io/apimachinery/pkg/util/diff",
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
],
)
go_library(
name = "go_default_library",
srcs = [
"describe.go",
"printers.go",
],
tags = ["automanaged"],
deps = [
"//federation/apis/federation:go_default_library",
"//federation/client/clientset_generated/federation_internalclientset:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/annotations:go_default_library",
"//pkg/api/events:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/apps:go_default_library",
"//pkg/apis/autoscaling:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/certificates:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/v1beta1:go_default_library",
"//pkg/apis/policy:go_default_library",
"//pkg/apis/rbac:go_default_library",
"//pkg/apis/storage:go_default_library",
"//pkg/apis/storage/util:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/clientset_generated/clientset/typed/core/v1:go_default_library",
"//pkg/client/clientset_generated/clientset/typed/extensions/v1beta1:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
"//pkg/client/clientset_generated/internalclientset/typed/extensions/internalversion:go_default_library",
"//pkg/controller/deployment/util:go_default_library",
"//pkg/fieldpath:go_default_library",
"//pkg/kubelet/qos:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/util/node:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:k8s.io/apimachinery/pkg/api/errors",
"//vendor:k8s.io/apimachinery/pkg/api/meta",
"//vendor:k8s.io/apimachinery/pkg/api/resource",
"//vendor:k8s.io/apimachinery/pkg/apis/meta/v1",
"//vendor:k8s.io/apimachinery/pkg/fields",
"//vendor:k8s.io/apimachinery/pkg/labels",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/types",
"//vendor:k8s.io/apimachinery/pkg/util/intstr",
"//vendor:k8s.io/apimachinery/pkg/util/sets",
"//vendor:k8s.io/client-go/dynamic",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
......@@ -40,6 +40,7 @@ import (
versionedfake "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/printers"
"k8s.io/kubernetes/pkg/util"
)
......@@ -59,7 +60,7 @@ func TestDescribePod(t *testing.T) {
})
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
d := PodDescriber{c}
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
out, err := d.Describe("foo", "bar", printers.DescriberSettings{ShowEvents: true})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
......@@ -83,7 +84,7 @@ func TestDescribePodTolerations(t *testing.T) {
})
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
d := PodDescriber{c}
out, err := d.Describe("foo", "bar", DescriberSettings{})
out, err := d.Describe("foo", "bar", printers.DescriberSettings{})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
......@@ -100,7 +101,7 @@ func TestDescribeNamespace(t *testing.T) {
})
c := &describeClient{T: t, Namespace: "", Interface: fake}
d := NamespaceDescriber{c}
out, err := d.Describe("", "myns", DescriberSettings{ShowEvents: true})
out, err := d.Describe("", "myns", printers.DescriberSettings{ShowEvents: true})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
......@@ -118,7 +119,7 @@ func TestDescribeService(t *testing.T) {
})
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
d := ServiceDescriber{c}
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
out, err := d.Describe("foo", "bar", printers.DescriberSettings{ShowEvents: true})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
......@@ -167,7 +168,7 @@ func TestPodDescribeResultsSorted(t *testing.T) {
d := PodDescriber{c}
// Act
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
out, err := d.Describe("foo", "bar", printers.DescriberSettings{ShowEvents: true})
// Assert
if err != nil {
......@@ -436,7 +437,7 @@ func TestDescribers(t *testing.T) {
if out, err := d.DescribeObject(first, second, third); out != "" || err == nil {
t.Errorf("unexpected result: %s %v", out, err)
} else {
if noDescriber, ok := err.(ErrNoDescriber); ok {
if noDescriber, ok := err.(printers.ErrNoDescriber); ok {
if !reflect.DeepEqual(noDescriber.Types, []string{"*api.Event", "*api.Pod", "*api.Pod"}) {
t.Errorf("unexpected describer: %v", err)
}
......@@ -649,7 +650,7 @@ func TestPersistentVolumeDescriber(t *testing.T) {
for name, pv := range tests {
fake := fake.NewSimpleClientset(pv)
c := PersistentVolumeDescriber{fake}
str, err := c.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
str, err := c.Describe("foo", "bar", printers.DescriberSettings{ShowEvents: true})
if err != nil {
t.Errorf("Unexpected error for test %s: %v", name, err)
}
......@@ -673,7 +674,7 @@ func TestDescribeDeployment(t *testing.T) {
},
})
d := DeploymentDescriber{fake, versionedFake}
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
out, err := d.Describe("foo", "bar", printers.DescriberSettings{ShowEvents: true})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
......@@ -707,7 +708,7 @@ func TestDescribeCluster(t *testing.T) {
}
fake := fedfake.NewSimpleClientset(&cluster)
d := ClusterDescriber{Interface: fake}
out, err := d.Describe("any", "foo", DescriberSettings{ShowEvents: true})
out, err := d.Describe("any", "foo", printers.DescriberSettings{ShowEvents: true})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
......@@ -732,7 +733,7 @@ func TestDescribeStorageClass(t *testing.T) {
},
})
s := StorageClassDescriber{f}
out, err := s.Describe("", "foo", DescriberSettings{ShowEvents: true})
out, err := s.Describe("", "foo", printers.DescriberSettings{ShowEvents: true})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
......@@ -756,7 +757,7 @@ func TestDescribePodDisruptionBudget(t *testing.T) {
},
})
s := PodDisruptionBudgetDescriber{f}
out, err := s.Describe("ns1", "pdb1", DescriberSettings{ShowEvents: true})
out, err := s.Describe("ns1", "pdb1", printers.DescriberSettings{ShowEvents: true})
if err != nil {
t.Errorf("unexpected error: %v", err)
}
......@@ -1112,7 +1113,7 @@ func TestDescribeHorizontalPodAutoscaler(t *testing.T) {
}
fake := fake.NewSimpleClientset(&test.hpa)
desc := HorizontalPodAutoscalerDescriber{fake}
str, err := desc.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
str, err := desc.Describe("foo", "bar", printers.DescriberSettings{ShowEvents: true})
if err != nil {
t.Errorf("Unexpected error for test %s: %v", test.name, err)
}
......@@ -1141,7 +1142,7 @@ func TestDescribeEvents(t *testing.T) {
},
}
m := map[string]Describer{
m := map[string]printers.Describer{
"DaemonSetDescriber": &DaemonSetDescriber{
fake.NewSimpleClientset(&extensions.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
......@@ -1241,7 +1242,7 @@ func TestDescribeEvents(t *testing.T) {
}
for name, d := range m {
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true})
out, err := d.Describe("foo", "bar", printers.DescriberSettings{ShowEvents: true})
if err != nil {
t.Errorf("unexpected error for %q: %v", name, err)
}
......@@ -1252,7 +1253,7 @@ func TestDescribeEvents(t *testing.T) {
t.Errorf("events not found for %q when ShowEvents=true: %s", name, out)
}
out, err = d.Describe("foo", "bar", DescriberSettings{ShowEvents: false})
out, err = d.Describe("foo", "bar", printers.DescriberSettings{ShowEvents: false})
if err != nil {
t.Errorf("unexpected error for %q: %s", name, err)
}
......
......@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package kubectl
package internalversion
import (
"reflect"
......
......@@ -27,7 +27,6 @@ const (
tabwriterPadding = 3
tabwriterPadChar = ' '
tabwriterFlags = 0
loadBalancerWidth = 16
)
// GetNewTabWriter returns a tabwriter that translates tabbed columns in input into properly aligned text.
......
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