Refactor printers to separate typed printers from generic code

parent 6d1c7308
...@@ -13,7 +13,7 @@ go_library( ...@@ -13,7 +13,7 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api:go_default_library", "//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",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema", "//vendor:k8s.io/apimachinery/pkg/runtime/schema",
"//vendor:k8s.io/apimachinery/pkg/util/validation/field", "//vendor:k8s.io/apimachinery/pkg/util/validation/field",
......
...@@ -30,7 +30,7 @@ import ( ...@@ -30,7 +30,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/api" "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 // Based on: https://github.com/openshift/origin/blob/master/pkg/api/compatibility_test.go
...@@ -94,7 +94,7 @@ func TestCompatibility( ...@@ -94,7 +94,7 @@ func TestCompatibility(
} }
if hasError { if hasError {
printer := new(kubectl.JSONPrinter) printer := &printers.JSONPrinter{}
printer.PrintObj(obj, os.Stdout) printer.PrintObj(obj, os.Stdout)
t.Logf("2: Encoded value: %#v", string(output)) t.Logf("2: Encoded value: %#v", string(output))
} }
......
...@@ -63,6 +63,7 @@ go_test( ...@@ -63,6 +63,7 @@ go_test(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/install:go_default_library",
"//pkg/api/testing/compat:go_default_library", "//pkg/api/testing/compat:go_default_library",
"//pkg/api/v1:go_default_library", "//pkg/api/v1:go_default_library",
"//pkg/api/validation:go_default_library", "//pkg/api/validation:go_default_library",
......
...@@ -25,6 +25,8 @@ import ( ...@@ -25,6 +25,8 @@ import (
"k8s.io/kubernetes/pkg/api/testing/compat" "k8s.io/kubernetes/pkg/api/testing/compat"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/validation" "k8s.io/kubernetes/pkg/api/validation"
_ "k8s.io/kubernetes/pkg/api/install"
) )
func TestCompatibility_v1_PodSecurityContext(t *testing.T) { 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 ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubectl package printers
import ( import (
"bufio" "bufio"
...@@ -41,14 +41,14 @@ const ( ...@@ -41,14 +41,14 @@ const (
var jsonRegexp = regexp.MustCompile("^\\{\\.?([^{}]+)\\}$|^\\.?([^{}]+)$") 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 '.' or curly brances '{...}'
// * {metadata.name} (no leading '.') // * {metadata.name} (no leading '.')
// * .metadata.name (no curly braces '{...}') // * .metadata.name (no curly braces '{...}')
// * {.metadata.name} (complete expression) // * {.metadata.name} (complete expression)
// And transforms them all into a valid jsonpat expression: // And transforms them all into a valid jsonpath expression:
// {.metadata.name} // {.metadata.name}
func massageJSONPath(pathExpression string) (string, error) { func RelaxedJSONPathExpression(pathExpression string) (string, error) {
if len(pathExpression) == 0 { if len(pathExpression) == 0 {
return pathExpression, nil return pathExpression, nil
} }
...@@ -84,7 +84,7 @@ func NewCustomColumnsPrinterFromSpec(spec string, decoder runtime.Decoder, noHea ...@@ -84,7 +84,7 @@ func NewCustomColumnsPrinterFromSpec(spec string, decoder runtime.Decoder, noHea
if len(colSpec) != 2 { if len(colSpec) != 2 {
return nil, fmt.Errorf("unexpected custom-columns spec: %s, expected <header>:<json-path-expr>", parts[ix]) 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 { if err != nil {
return nil, err return nil, err
} }
...@@ -126,7 +126,7 @@ func NewCustomColumnsPrinterFromTemplate(templateReader io.Reader, decoder runti ...@@ -126,7 +126,7 @@ func NewCustomColumnsPrinterFromTemplate(templateReader io.Reader, decoder runti
columns := make([]Column, len(headers)) columns := make([]Column, len(headers))
for ix := range headers { for ix := range headers {
spec, err := massageJSONPath(specs[ix]) spec, err := RelaxedJSONPathExpression(specs[ix])
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubectl package printers_test
import ( import (
"bytes" "bytes"
...@@ -26,6 +26,7 @@ import ( ...@@ -26,6 +26,7 @@ import (
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/printers"
) )
func TestMassageJSONPath(t *testing.T) { func TestMassageJSONPath(t *testing.T) {
...@@ -45,7 +46,7 @@ func TestMassageJSONPath(t *testing.T) { ...@@ -45,7 +46,7 @@ func TestMassageJSONPath(t *testing.T) {
{input: "{{foo.bar}", expectErr: true}, {input: "{{foo.bar}", expectErr: true},
} }
for _, test := range tests { for _, test := range tests {
output, err := massageJSONPath(test.input) output, err := printers.RelaxedJSONPathExpression(test.input)
if err != nil && !test.expectErr { if err != nil && !test.expectErr {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
continue continue
...@@ -65,7 +66,7 @@ func TestMassageJSONPath(t *testing.T) { ...@@ -65,7 +66,7 @@ func TestMassageJSONPath(t *testing.T) {
func TestNewColumnPrinterFromSpec(t *testing.T) { func TestNewColumnPrinterFromSpec(t *testing.T) {
tests := []struct { tests := []struct {
spec string spec string
expectedColumns []Column expectedColumns []printers.Column
expectErr bool expectErr bool
name string name string
noHeaders bool noHeaders bool
...@@ -93,7 +94,7 @@ func TestNewColumnPrinterFromSpec(t *testing.T) { ...@@ -93,7 +94,7 @@ func TestNewColumnPrinterFromSpec(t *testing.T) {
{ {
spec: "NAME:metadata.name,API_VERSION:apiVersion", spec: "NAME:metadata.name,API_VERSION:apiVersion",
name: "ok", name: "ok",
expectedColumns: []Column{ expectedColumns: []printers.Column{
{ {
Header: "NAME", Header: "NAME",
FieldSpec: "{.metadata.name}", FieldSpec: "{.metadata.name}",
...@@ -111,7 +112,7 @@ func TestNewColumnPrinterFromSpec(t *testing.T) { ...@@ -111,7 +112,7 @@ func TestNewColumnPrinterFromSpec(t *testing.T) {
}, },
} }
for _, test := range tests { 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 test.expectErr {
if err == nil { if err == nil {
t.Errorf("[%s] unexpected non-error", test.name) t.Errorf("[%s] unexpected non-error", test.name)
...@@ -141,6 +142,15 @@ func TestNewColumnPrinterFromSpec(t *testing.T) { ...@@ -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 const exampleTemplateOne = `NAME API_VERSION
{metadata.name} {apiVersion}` {metadata.name} {apiVersion}`
...@@ -150,7 +160,7 @@ const exampleTemplateTwo = `NAME API_VERSION ...@@ -150,7 +160,7 @@ const exampleTemplateTwo = `NAME API_VERSION
func TestNewColumnPrinterFromTemplate(t *testing.T) { func TestNewColumnPrinterFromTemplate(t *testing.T) {
tests := []struct { tests := []struct {
spec string spec string
expectedColumns []Column expectedColumns []printers.Column
expectErr bool expectErr bool
name string name string
}{ }{
...@@ -177,7 +187,7 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) { ...@@ -177,7 +187,7 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) {
{ {
spec: exampleTemplateOne, spec: exampleTemplateOne,
name: "ok", name: "ok",
expectedColumns: []Column{ expectedColumns: []printers.Column{
{ {
Header: "NAME", Header: "NAME",
FieldSpec: "{.metadata.name}", FieldSpec: "{.metadata.name}",
...@@ -191,7 +201,7 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) { ...@@ -191,7 +201,7 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) {
{ {
spec: exampleTemplateTwo, spec: exampleTemplateTwo,
name: "ok-2", name: "ok-2",
expectedColumns: []Column{ expectedColumns: []printers.Column{
{ {
Header: "NAME", Header: "NAME",
FieldSpec: "{.metadata.name}", FieldSpec: "{.metadata.name}",
...@@ -205,7 +215,7 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) { ...@@ -205,7 +215,7 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) {
} }
for _, test := range tests { for _, test := range tests {
reader := bytes.NewBufferString(test.spec) reader := bytes.NewBufferString(test.spec)
printer, err := NewCustomColumnsPrinterFromTemplate(reader, api.Codecs.UniversalDecoder()) printer, err := printers.NewCustomColumnsPrinterFromTemplate(reader, api.Codecs.UniversalDecoder())
if test.expectErr { if test.expectErr {
if err == nil { if err == nil {
t.Errorf("[%s] unexpected non-error", test.name) t.Errorf("[%s] unexpected non-error", test.name)
...@@ -226,12 +236,12 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) { ...@@ -226,12 +236,12 @@ func TestNewColumnPrinterFromTemplate(t *testing.T) {
func TestColumnPrint(t *testing.T) { func TestColumnPrint(t *testing.T) {
tests := []struct { tests := []struct {
columns []Column columns []printers.Column
obj runtime.Object obj runtime.Object
expectedOutput string expectedOutput string
}{ }{
{ {
columns: []Column{ columns: []printers.Column{
{ {
Header: "NAME", Header: "NAME",
FieldSpec: "{.metadata.name}", FieldSpec: "{.metadata.name}",
...@@ -243,7 +253,7 @@ foo ...@@ -243,7 +253,7 @@ foo
`, `,
}, },
{ {
columns: []Column{ columns: []printers.Column{
{ {
Header: "NAME", Header: "NAME",
FieldSpec: "{.metadata.name}", FieldSpec: "{.metadata.name}",
...@@ -261,7 +271,7 @@ bar ...@@ -261,7 +271,7 @@ bar
`, `,
}, },
{ {
columns: []Column{ columns: []printers.Column{
{ {
Header: "NAME", Header: "NAME",
FieldSpec: "{.metadata.name}", FieldSpec: "{.metadata.name}",
...@@ -279,7 +289,7 @@ foo baz ...@@ -279,7 +289,7 @@ foo baz
} }
for _, test := range tests { for _, test := range tests {
printer := &CustomColumnsPrinter{ printer := &printers.CustomColumnsPrinter{
Columns: test.columns, Columns: test.columns,
Decoder: api.Codecs.UniversalDecoder(), Decoder: api.Codecs.UniversalDecoder(),
} }
......
...@@ -17,14 +17,23 @@ limitations under the License. ...@@ -17,14 +17,23 @@ limitations under the License.
package printers package printers
import ( import (
"bytes"
"fmt" "fmt"
"io" "io"
"reflect" "reflect"
"strings" "strings"
"text/tabwriter"
"github.com/golang/glog" "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 { type handlerEntry struct {
columns []string columns []string
columnsWithWide []string columnsWithWide []string
...@@ -49,20 +58,9 @@ func NewHumanReadablePrinter(options PrintOptions) *HumanReadablePrinter { ...@@ -49,20 +58,9 @@ func NewHumanReadablePrinter(options PrintOptions) *HumanReadablePrinter {
handlerMap: make(map[reflect.Type]*handlerEntry), handlerMap: make(map[reflect.Type]*handlerEntry),
options: options, options: options,
} }
printer.addDefaultHandlers()
return printer 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 // GetResourceKind returns the type currently set for a resource
func (h *HumanReadablePrinter) GetResourceKind() string { func (h *HumanReadablePrinter) GetResourceKind() string {
return h.options.Kind return h.options.Kind
...@@ -157,3 +155,175 @@ func (h *HumanReadablePrinter) printHeader(columnNames []string, w io.Writer) er ...@@ -157,3 +155,175 @@ func (h *HumanReadablePrinter) printHeader(columnNames []string, w io.Writer) er
} }
return nil 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. ...@@ -17,6 +17,7 @@ limitations under the License.
package printers package printers
import ( import (
"fmt"
"io" "io"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
...@@ -60,3 +61,36 @@ type PrintOptions struct { ...@@ -60,3 +61,36 @@ type PrintOptions struct {
Kind string Kind string
ColumnLabels []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 ( ...@@ -40,6 +40,7 @@ import (
versionedfake "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/fake" 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"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/printers"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
) )
...@@ -59,7 +60,7 @@ func TestDescribePod(t *testing.T) { ...@@ -59,7 +60,7 @@ func TestDescribePod(t *testing.T) {
}) })
c := &describeClient{T: t, Namespace: "foo", Interface: fake} c := &describeClient{T: t, Namespace: "foo", Interface: fake}
d := PodDescriber{c} 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 { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
...@@ -83,7 +84,7 @@ func TestDescribePodTolerations(t *testing.T) { ...@@ -83,7 +84,7 @@ func TestDescribePodTolerations(t *testing.T) {
}) })
c := &describeClient{T: t, Namespace: "foo", Interface: fake} c := &describeClient{T: t, Namespace: "foo", Interface: fake}
d := PodDescriber{c} d := PodDescriber{c}
out, err := d.Describe("foo", "bar", DescriberSettings{}) out, err := d.Describe("foo", "bar", printers.DescriberSettings{})
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
...@@ -100,7 +101,7 @@ func TestDescribeNamespace(t *testing.T) { ...@@ -100,7 +101,7 @@ func TestDescribeNamespace(t *testing.T) {
}) })
c := &describeClient{T: t, Namespace: "", Interface: fake} c := &describeClient{T: t, Namespace: "", Interface: fake}
d := NamespaceDescriber{c} d := NamespaceDescriber{c}
out, err := d.Describe("", "myns", DescriberSettings{ShowEvents: true}) out, err := d.Describe("", "myns", printers.DescriberSettings{ShowEvents: true})
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
...@@ -118,7 +119,7 @@ func TestDescribeService(t *testing.T) { ...@@ -118,7 +119,7 @@ func TestDescribeService(t *testing.T) {
}) })
c := &describeClient{T: t, Namespace: "foo", Interface: fake} c := &describeClient{T: t, Namespace: "foo", Interface: fake}
d := ServiceDescriber{c} 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 { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
...@@ -167,7 +168,7 @@ func TestPodDescribeResultsSorted(t *testing.T) { ...@@ -167,7 +168,7 @@ func TestPodDescribeResultsSorted(t *testing.T) {
d := PodDescriber{c} d := PodDescriber{c}
// Act // Act
out, err := d.Describe("foo", "bar", DescriberSettings{ShowEvents: true}) out, err := d.Describe("foo", "bar", printers.DescriberSettings{ShowEvents: true})
// Assert // Assert
if err != nil { if err != nil {
...@@ -436,7 +437,7 @@ func TestDescribers(t *testing.T) { ...@@ -436,7 +437,7 @@ func TestDescribers(t *testing.T) {
if out, err := d.DescribeObject(first, second, third); out != "" || err == nil { if out, err := d.DescribeObject(first, second, third); out != "" || err == nil {
t.Errorf("unexpected result: %s %v", out, err) t.Errorf("unexpected result: %s %v", out, err)
} else { } 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"}) { if !reflect.DeepEqual(noDescriber.Types, []string{"*api.Event", "*api.Pod", "*api.Pod"}) {
t.Errorf("unexpected describer: %v", err) t.Errorf("unexpected describer: %v", err)
} }
...@@ -649,7 +650,7 @@ func TestPersistentVolumeDescriber(t *testing.T) { ...@@ -649,7 +650,7 @@ func TestPersistentVolumeDescriber(t *testing.T) {
for name, pv := range tests { for name, pv := range tests {
fake := fake.NewSimpleClientset(pv) fake := fake.NewSimpleClientset(pv)
c := PersistentVolumeDescriber{fake} 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 { if err != nil {
t.Errorf("Unexpected error for test %s: %v", name, err) t.Errorf("Unexpected error for test %s: %v", name, err)
} }
...@@ -673,7 +674,7 @@ func TestDescribeDeployment(t *testing.T) { ...@@ -673,7 +674,7 @@ func TestDescribeDeployment(t *testing.T) {
}, },
}) })
d := DeploymentDescriber{fake, versionedFake} 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 { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
...@@ -707,7 +708,7 @@ func TestDescribeCluster(t *testing.T) { ...@@ -707,7 +708,7 @@ func TestDescribeCluster(t *testing.T) {
} }
fake := fedfake.NewSimpleClientset(&cluster) fake := fedfake.NewSimpleClientset(&cluster)
d := ClusterDescriber{Interface: fake} 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 { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
...@@ -732,7 +733,7 @@ func TestDescribeStorageClass(t *testing.T) { ...@@ -732,7 +733,7 @@ func TestDescribeStorageClass(t *testing.T) {
}, },
}) })
s := StorageClassDescriber{f} s := StorageClassDescriber{f}
out, err := s.Describe("", "foo", DescriberSettings{ShowEvents: true}) out, err := s.Describe("", "foo", printers.DescriberSettings{ShowEvents: true})
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
...@@ -756,7 +757,7 @@ func TestDescribePodDisruptionBudget(t *testing.T) { ...@@ -756,7 +757,7 @@ func TestDescribePodDisruptionBudget(t *testing.T) {
}, },
}) })
s := PodDisruptionBudgetDescriber{f} 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 { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
...@@ -1112,7 +1113,7 @@ func TestDescribeHorizontalPodAutoscaler(t *testing.T) { ...@@ -1112,7 +1113,7 @@ func TestDescribeHorizontalPodAutoscaler(t *testing.T) {
} }
fake := fake.NewSimpleClientset(&test.hpa) fake := fake.NewSimpleClientset(&test.hpa)
desc := HorizontalPodAutoscalerDescriber{fake} 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 { if err != nil {
t.Errorf("Unexpected error for test %s: %v", test.name, err) t.Errorf("Unexpected error for test %s: %v", test.name, err)
} }
...@@ -1141,7 +1142,7 @@ func TestDescribeEvents(t *testing.T) { ...@@ -1141,7 +1142,7 @@ func TestDescribeEvents(t *testing.T) {
}, },
} }
m := map[string]Describer{ m := map[string]printers.Describer{
"DaemonSetDescriber": &DaemonSetDescriber{ "DaemonSetDescriber": &DaemonSetDescriber{
fake.NewSimpleClientset(&extensions.DaemonSet{ fake.NewSimpleClientset(&extensions.DaemonSet{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
...@@ -1241,7 +1242,7 @@ func TestDescribeEvents(t *testing.T) { ...@@ -1241,7 +1242,7 @@ func TestDescribeEvents(t *testing.T) {
} }
for name, d := range m { 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 { if err != nil {
t.Errorf("unexpected error for %q: %v", name, err) t.Errorf("unexpected error for %q: %v", name, err)
} }
...@@ -1252,7 +1253,7 @@ func TestDescribeEvents(t *testing.T) { ...@@ -1252,7 +1253,7 @@ func TestDescribeEvents(t *testing.T) {
t.Errorf("events not found for %q when ShowEvents=true: %s", name, out) 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 { if err != nil {
t.Errorf("unexpected error for %q: %s", name, err) t.Errorf("unexpected error for %q: %s", name, err)
} }
......
...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and ...@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
package kubectl package internalversion
import ( import (
"reflect" "reflect"
......
...@@ -27,7 +27,6 @@ const ( ...@@ -27,7 +27,6 @@ const (
tabwriterPadding = 3 tabwriterPadding = 3
tabwriterPadChar = ' ' tabwriterPadChar = ' '
tabwriterFlags = 0 tabwriterFlags = 0
loadBalancerWidth = 16
) )
// GetNewTabWriter returns a tabwriter that translates tabbed columns in input into properly aligned text. // 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