mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 18:53:35 +00:00
Fresh dep ensure
This commit is contained in:
38
vendor/k8s.io/kubernetes/pkg/printers/BUILD
generated
vendored
38
vendor/k8s.io/kubernetes/pkg/printers/BUILD
generated
vendored
@ -9,27 +9,20 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"customcolumn.go",
|
||||
"customcolumn_flags.go",
|
||||
"humanreadable.go",
|
||||
"interface.go",
|
||||
"tabwriter.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/printers",
|
||||
deps = [
|
||||
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||
"//pkg/kubectl/genericclioptions/printers:go_default_library",
|
||||
"//pkg/kubectl/scheme:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra: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/v1/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1: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/util/runtime:go_default_library",
|
||||
"//vendor/k8s.io/client-go/util/jsonpath:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -52,19 +45,12 @@ filegroup(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"customcolumn_flags_test.go",
|
||||
"customcolumn_test.go",
|
||||
"humanreadable_test.go",
|
||||
],
|
||||
srcs = ["humanreadable_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
242
vendor/k8s.io/kubernetes/pkg/printers/customcolumn.go
generated
vendored
242
vendor/k8s.io/kubernetes/pkg/printers/customcolumn.go
generated
vendored
@ -1,242 +0,0 @@
|
||||
/*
|
||||
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 (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/util/jsonpath"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers"
|
||||
)
|
||||
|
||||
var jsonRegexp = regexp.MustCompile("^\\{\\.?([^{}]+)\\}$|^\\.?([^{}]+)$")
|
||||
|
||||
// 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 jsonpath expression:
|
||||
// {.metadata.name}
|
||||
func RelaxedJSONPathExpression(pathExpression string) (string, error) {
|
||||
if len(pathExpression) == 0 {
|
||||
return pathExpression, nil
|
||||
}
|
||||
submatches := jsonRegexp.FindStringSubmatch(pathExpression)
|
||||
if submatches == nil {
|
||||
return "", fmt.Errorf("unexpected path string, expected a 'name1.name2' or '.name1.name2' or '{name1.name2}' or '{.name1.name2}'")
|
||||
}
|
||||
if len(submatches) != 3 {
|
||||
return "", fmt.Errorf("unexpected submatch list: %v", submatches)
|
||||
}
|
||||
var fieldSpec string
|
||||
if len(submatches[1]) != 0 {
|
||||
fieldSpec = submatches[1]
|
||||
} else {
|
||||
fieldSpec = submatches[2]
|
||||
}
|
||||
return fmt.Sprintf("{.%s}", fieldSpec), nil
|
||||
}
|
||||
|
||||
// NewCustomColumnsPrinterFromSpec creates a custom columns printer from a comma separated list of <header>:<jsonpath-field-spec> pairs.
|
||||
// e.g. NAME:metadata.name,API_VERSION:apiVersion creates a printer that prints:
|
||||
//
|
||||
// NAME API_VERSION
|
||||
// foo bar
|
||||
func NewCustomColumnsPrinterFromSpec(spec string, decoder runtime.Decoder, noHeaders bool) (*CustomColumnsPrinter, error) {
|
||||
if len(spec) == 0 {
|
||||
return nil, fmt.Errorf("custom-columns format specified but no custom columns given")
|
||||
}
|
||||
parts := strings.Split(spec, ",")
|
||||
columns := make([]Column, len(parts))
|
||||
for ix := range parts {
|
||||
colSpec := strings.Split(parts[ix], ":")
|
||||
if len(colSpec) != 2 {
|
||||
return nil, fmt.Errorf("unexpected custom-columns spec: %s, expected <header>:<json-path-expr>", parts[ix])
|
||||
}
|
||||
spec, err := RelaxedJSONPathExpression(colSpec[1])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
columns[ix] = Column{Header: colSpec[0], FieldSpec: spec}
|
||||
}
|
||||
return &CustomColumnsPrinter{Columns: columns, Decoder: decoder, NoHeaders: noHeaders}, nil
|
||||
}
|
||||
|
||||
func splitOnWhitespace(line string) []string {
|
||||
lineScanner := bufio.NewScanner(bytes.NewBufferString(line))
|
||||
lineScanner.Split(bufio.ScanWords)
|
||||
result := []string{}
|
||||
for lineScanner.Scan() {
|
||||
result = append(result, lineScanner.Text())
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// NewCustomColumnsPrinterFromTemplate creates a custom columns printer from a template stream. The template is expected
|
||||
// to consist of two lines, whitespace separated. The first line is the header line, the second line is the jsonpath field spec
|
||||
// For example, the template below:
|
||||
// NAME API_VERSION
|
||||
// {metadata.name} {apiVersion}
|
||||
func NewCustomColumnsPrinterFromTemplate(templateReader io.Reader, decoder runtime.Decoder) (*CustomColumnsPrinter, error) {
|
||||
scanner := bufio.NewScanner(templateReader)
|
||||
if !scanner.Scan() {
|
||||
return nil, fmt.Errorf("invalid template, missing header line. Expected format is one line of space separated headers, one line of space separated column specs.")
|
||||
}
|
||||
headers := splitOnWhitespace(scanner.Text())
|
||||
|
||||
if !scanner.Scan() {
|
||||
return nil, fmt.Errorf("invalid template, missing spec line. Expected format is one line of space separated headers, one line of space separated column specs.")
|
||||
}
|
||||
specs := splitOnWhitespace(scanner.Text())
|
||||
|
||||
if len(headers) != len(specs) {
|
||||
return nil, fmt.Errorf("number of headers (%d) and field specifications (%d) don't match", len(headers), len(specs))
|
||||
}
|
||||
|
||||
columns := make([]Column, len(headers))
|
||||
for ix := range headers {
|
||||
spec, err := RelaxedJSONPathExpression(specs[ix])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
columns[ix] = Column{
|
||||
Header: headers[ix],
|
||||
FieldSpec: spec,
|
||||
}
|
||||
}
|
||||
return &CustomColumnsPrinter{Columns: columns, Decoder: decoder, NoHeaders: false}, nil
|
||||
}
|
||||
|
||||
// Column represents a user specified column
|
||||
type Column struct {
|
||||
// The header to print above the column, general style is ALL_CAPS
|
||||
Header string
|
||||
// The pointer to the field in the object to print in JSONPath form
|
||||
// e.g. {.ObjectMeta.Name}, see pkg/util/jsonpath for more details.
|
||||
FieldSpec string
|
||||
}
|
||||
|
||||
// CustomColumnPrinter is a printer that knows how to print arbitrary columns
|
||||
// of data from templates specified in the `Columns` array
|
||||
type CustomColumnsPrinter struct {
|
||||
Columns []Column
|
||||
Decoder runtime.Decoder
|
||||
NoHeaders bool
|
||||
// lastType records type of resource printed last so that we don't repeat
|
||||
// header while printing same type of resources.
|
||||
lastType reflect.Type
|
||||
}
|
||||
|
||||
func (s *CustomColumnsPrinter) PrintObj(obj runtime.Object, out io.Writer) error {
|
||||
// we use reflect.Indirect here in order to obtain the actual value from a pointer.
|
||||
// we need an actual value in order to retrieve the package path for an object.
|
||||
// using reflect.Indirect indiscriminately is valid here, as all runtime.Objects are supposed to be pointers.
|
||||
if printers.InternalObjectPreventer.IsForbidden(reflect.Indirect(reflect.ValueOf(obj)).Type().PkgPath()) {
|
||||
return fmt.Errorf(printers.InternalObjectPrinterErr)
|
||||
}
|
||||
|
||||
if w, found := out.(*tabwriter.Writer); !found {
|
||||
w = GetNewTabWriter(out)
|
||||
out = w
|
||||
defer w.Flush()
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(obj)
|
||||
if !s.NoHeaders && t != s.lastType {
|
||||
headers := make([]string, len(s.Columns))
|
||||
for ix := range s.Columns {
|
||||
headers[ix] = s.Columns[ix].Header
|
||||
}
|
||||
fmt.Fprintln(out, strings.Join(headers, "\t"))
|
||||
s.lastType = t
|
||||
}
|
||||
parsers := make([]*jsonpath.JSONPath, len(s.Columns))
|
||||
for ix := range s.Columns {
|
||||
parsers[ix] = jsonpath.New(fmt.Sprintf("column%d", ix)).AllowMissingKeys(true)
|
||||
if err := parsers[ix].Parse(s.Columns[ix].FieldSpec); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if meta.IsListType(obj) {
|
||||
objs, err := meta.ExtractList(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for ix := range objs {
|
||||
if err := s.printOneObject(objs[ix], parsers, out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err := s.printOneObject(obj, parsers, out); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *CustomColumnsPrinter) printOneObject(obj runtime.Object, parsers []*jsonpath.JSONPath, out io.Writer) error {
|
||||
columns := make([]string, len(parsers))
|
||||
switch u := obj.(type) {
|
||||
case *runtime.Unknown:
|
||||
if len(u.Raw) > 0 {
|
||||
var err error
|
||||
if obj, err = runtime.Decode(s.Decoder, u.Raw); err != nil {
|
||||
return fmt.Errorf("can't decode object for printing: %v (%s)", err, u.Raw)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ix := range parsers {
|
||||
parser := parsers[ix]
|
||||
|
||||
var values [][]reflect.Value
|
||||
var err error
|
||||
if unstructured, ok := obj.(runtime.Unstructured); ok {
|
||||
values, err = parser.FindResults(unstructured.UnstructuredContent())
|
||||
} else {
|
||||
values, err = parser.FindResults(reflect.ValueOf(obj).Elem().Interface())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
valueStrings := []string{}
|
||||
if len(values) == 0 || len(values[0]) == 0 {
|
||||
valueStrings = append(valueStrings, "<none>")
|
||||
}
|
||||
for arrIx := range values {
|
||||
for valIx := range values[arrIx] {
|
||||
valueStrings = append(valueStrings, fmt.Sprintf("%v", values[arrIx][valIx].Interface()))
|
||||
}
|
||||
}
|
||||
columns[ix] = strings.Join(valueStrings, ",")
|
||||
}
|
||||
fmt.Fprintln(out, strings.Join(columns, "\t"))
|
||||
return nil
|
||||
}
|
109
vendor/k8s.io/kubernetes/pkg/printers/customcolumn_flags.go
generated
vendored
109
vendor/k8s.io/kubernetes/pkg/printers/customcolumn_flags.go
generated
vendored
@ -1,109 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
)
|
||||
|
||||
var columnsFormats = map[string]bool{
|
||||
"custom-columns-file": true,
|
||||
"custom-columns": true,
|
||||
}
|
||||
|
||||
// CustomColumnsPrintFlags provides default flags necessary for printing
|
||||
// custom resource columns from an inline-template or file.
|
||||
type CustomColumnsPrintFlags struct {
|
||||
NoHeaders bool
|
||||
TemplateArgument string
|
||||
}
|
||||
|
||||
func (f *CustomColumnsPrintFlags) AllowedFormats() []string {
|
||||
formats := make([]string, 0, len(columnsFormats))
|
||||
for format := range columnsFormats {
|
||||
formats = append(formats, format)
|
||||
}
|
||||
return formats
|
||||
}
|
||||
|
||||
// ToPrinter receives an templateFormat and returns a printer capable of
|
||||
// handling custom-column printing.
|
||||
// Returns false if the specified templateFormat does not match a supported format.
|
||||
// Supported format types can be found in pkg/printers/printers.go
|
||||
func (f *CustomColumnsPrintFlags) ToPrinter(templateFormat string) (ResourcePrinter, error) {
|
||||
if len(templateFormat) == 0 {
|
||||
return nil, genericclioptions.NoCompatiblePrinterError{}
|
||||
}
|
||||
|
||||
templateValue := ""
|
||||
|
||||
if len(f.TemplateArgument) == 0 {
|
||||
for format := range columnsFormats {
|
||||
format = format + "="
|
||||
if strings.HasPrefix(templateFormat, format) {
|
||||
templateValue = templateFormat[len(format):]
|
||||
templateFormat = format[:len(format)-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
templateValue = f.TemplateArgument
|
||||
}
|
||||
|
||||
if _, supportedFormat := columnsFormats[templateFormat]; !supportedFormat {
|
||||
return nil, genericclioptions.NoCompatiblePrinterError{OutputFormat: &templateFormat, AllowedFormats: f.AllowedFormats()}
|
||||
}
|
||||
|
||||
if len(templateValue) == 0 {
|
||||
return nil, fmt.Errorf("custom-columns format specified but no custom columns given")
|
||||
}
|
||||
|
||||
decoder := scheme.Codecs.UniversalDecoder()
|
||||
|
||||
if templateFormat == "custom-columns-file" {
|
||||
file, err := os.Open(templateValue)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading template %s, %v\n", templateValue, err)
|
||||
}
|
||||
defer file.Close()
|
||||
p, err := NewCustomColumnsPrinterFromTemplate(file, decoder)
|
||||
return p, err
|
||||
}
|
||||
|
||||
return NewCustomColumnsPrinterFromSpec(templateValue, decoder, f.NoHeaders)
|
||||
}
|
||||
|
||||
// AddFlags receives a *cobra.Command reference and binds
|
||||
// flags related to custom-columns printing
|
||||
func (f *CustomColumnsPrintFlags) AddFlags(c *cobra.Command) {}
|
||||
|
||||
// NewCustomColumnsPrintFlags returns flags associated with
|
||||
// custom-column printing, with default values set.
|
||||
// NoHeaders and TemplateArgument should be set by callers.
|
||||
func NewCustomColumnsPrintFlags() *CustomColumnsPrintFlags {
|
||||
return &CustomColumnsPrintFlags{
|
||||
NoHeaders: false,
|
||||
TemplateArgument: "",
|
||||
}
|
||||
}
|
139
vendor/k8s.io/kubernetes/pkg/printers/customcolumn_flags_test.go
generated
vendored
139
vendor/k8s.io/kubernetes/pkg/printers/customcolumn_flags_test.go
generated
vendored
@ -1,139 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 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 (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
)
|
||||
|
||||
func TestPrinterSupportsExpectedCustomColumnFormats(t *testing.T) {
|
||||
testObject := &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
|
||||
|
||||
customColumnsFile, err := ioutil.TempFile("", "printers_jsonpath_flags")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
defer func(tempFile *os.File) {
|
||||
tempFile.Close()
|
||||
os.Remove(tempFile.Name())
|
||||
}(customColumnsFile)
|
||||
|
||||
fmt.Fprintf(customColumnsFile, "NAME\n.metadata.name")
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
outputFormat string
|
||||
templateArg string
|
||||
expectedError string
|
||||
expectedParseError string
|
||||
expectedOutput string
|
||||
expectNoMatch bool
|
||||
}{
|
||||
{
|
||||
name: "valid output format also containing the custom-columns argument succeeds",
|
||||
outputFormat: "custom-columns=NAME:.metadata.name",
|
||||
expectedOutput: "foo",
|
||||
},
|
||||
{
|
||||
name: "valid output format and no --template argument results in an error",
|
||||
outputFormat: "custom-columns",
|
||||
expectedError: "custom-columns format specified but no custom columns given",
|
||||
},
|
||||
{
|
||||
name: "valid output format and --template argument succeeds",
|
||||
outputFormat: "custom-columns",
|
||||
templateArg: "NAME:.metadata.name",
|
||||
expectedOutput: "foo",
|
||||
},
|
||||
{
|
||||
name: "custom-columns template file should match, and successfully return correct value",
|
||||
outputFormat: "custom-columns-file",
|
||||
templateArg: customColumnsFile.Name(),
|
||||
expectedOutput: "foo",
|
||||
},
|
||||
{
|
||||
name: "valid output format and invalid --template argument results in a parsing error from the printer",
|
||||
outputFormat: "custom-columns",
|
||||
templateArg: "invalid",
|
||||
expectedError: "unexpected custom-columns spec: invalid, expected <header>:<json-path-expr>",
|
||||
},
|
||||
{
|
||||
name: "no printer is matched on an invalid outputFormat",
|
||||
outputFormat: "invalid",
|
||||
expectNoMatch: true,
|
||||
},
|
||||
{
|
||||
name: "custom-columns printer should not match on any other format supported by another printer",
|
||||
outputFormat: "go-template",
|
||||
expectNoMatch: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
printFlags := CustomColumnsPrintFlags{
|
||||
TemplateArgument: tc.templateArg,
|
||||
}
|
||||
|
||||
p, err := printFlags.ToPrinter(tc.outputFormat)
|
||||
if tc.expectNoMatch {
|
||||
if !genericclioptions.IsNoCompatiblePrinterError(err) {
|
||||
t.Fatalf("expected no printer matches for output format %q", tc.outputFormat)
|
||||
}
|
||||
return
|
||||
}
|
||||
if genericclioptions.IsNoCompatiblePrinterError(err) {
|
||||
t.Fatalf("expected to match template printer for output format %q", tc.outputFormat)
|
||||
}
|
||||
|
||||
if len(tc.expectedError) > 0 {
|
||||
if err == nil || !strings.Contains(err.Error(), tc.expectedError) {
|
||||
t.Errorf("expecting error %q, got %v", tc.expectedError, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
out := bytes.NewBuffer([]byte{})
|
||||
err = p.PrintObj(testObject, out)
|
||||
if len(tc.expectedParseError) > 0 {
|
||||
if err == nil || !strings.Contains(err.Error(), tc.expectedParseError) {
|
||||
t.Errorf("expecting error %q, got %v", tc.expectedError, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if !strings.Contains(out.String(), tc.expectedOutput) {
|
||||
t.Errorf("unexpected output: expecting %q, got %q", tc.expectedOutput, out.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
372
vendor/k8s.io/kubernetes/pkg/printers/customcolumn_test.go
generated
vendored
372
vendor/k8s.io/kubernetes/pkg/printers/customcolumn_test.go
generated
vendored
@ -1,372 +0,0 @@
|
||||
/*
|
||||
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 (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
func TestMassageJSONPath(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expectedOutput string
|
||||
expectErr bool
|
||||
}{
|
||||
{input: "foo.bar", expectedOutput: "{.foo.bar}"},
|
||||
{input: "{foo.bar}", expectedOutput: "{.foo.bar}"},
|
||||
{input: ".foo.bar", expectedOutput: "{.foo.bar}"},
|
||||
{input: "{.foo.bar}", expectedOutput: "{.foo.bar}"},
|
||||
{input: "", expectedOutput: ""},
|
||||
{input: "{foo.bar", expectErr: true},
|
||||
{input: "foo.bar}", expectErr: true},
|
||||
{input: "{foo.bar}}", expectErr: true},
|
||||
{input: "{{foo.bar}", expectErr: true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.input, func(t *testing.T) {
|
||||
output, err := RelaxedJSONPathExpression(test.input)
|
||||
if err != nil && !test.expectErr {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
return
|
||||
}
|
||||
if test.expectErr {
|
||||
if err == nil {
|
||||
t.Error("unexpected non-error")
|
||||
}
|
||||
return
|
||||
}
|
||||
if output != test.expectedOutput {
|
||||
t.Errorf("input: %s, expected: %s, saw: %s", test.input, test.expectedOutput, output)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewColumnPrinterFromSpec(t *testing.T) {
|
||||
tests := []struct {
|
||||
spec string
|
||||
expectedColumns []Column
|
||||
expectErr bool
|
||||
name string
|
||||
noHeaders bool
|
||||
}{
|
||||
{
|
||||
spec: "",
|
||||
expectErr: true,
|
||||
name: "empty",
|
||||
},
|
||||
{
|
||||
spec: "invalid",
|
||||
expectErr: true,
|
||||
name: "invalid1",
|
||||
},
|
||||
{
|
||||
spec: "invalid=foobar",
|
||||
expectErr: true,
|
||||
name: "invalid2",
|
||||
},
|
||||
{
|
||||
spec: "invalid,foobar:blah",
|
||||
expectErr: true,
|
||||
name: "invalid3",
|
||||
},
|
||||
{
|
||||
spec: "NAME:metadata.name,API_VERSION:apiVersion",
|
||||
name: "ok",
|
||||
expectedColumns: []Column{
|
||||
{
|
||||
Header: "NAME",
|
||||
FieldSpec: "{.metadata.name}",
|
||||
},
|
||||
{
|
||||
Header: "API_VERSION",
|
||||
FieldSpec: "{.apiVersion}",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
spec: "API_VERSION:apiVersion",
|
||||
name: "no-headers",
|
||||
noHeaders: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
printer, err := NewCustomColumnsPrinterFromSpec(test.spec, legacyscheme.Codecs.UniversalDecoder(), test.noHeaders)
|
||||
if test.expectErr {
|
||||
if err == nil {
|
||||
t.Errorf("[%s] unexpected non-error", test.name)
|
||||
}
|
||||
return
|
||||
}
|
||||
if !test.expectErr && err != nil {
|
||||
t.Errorf("[%s] unexpected error: %v", test.name, err)
|
||||
return
|
||||
}
|
||||
if test.noHeaders {
|
||||
buffer := &bytes.Buffer{}
|
||||
|
||||
printer.PrintObj(&api.Pod{}, buffer)
|
||||
if err != nil {
|
||||
t.Fatalf("An error occurred printing Pod: %#v", err)
|
||||
}
|
||||
|
||||
if contains(strings.Fields(buffer.String()), "API_VERSION") {
|
||||
t.Errorf("unexpected header API_VERSION")
|
||||
}
|
||||
|
||||
} else if !reflect.DeepEqual(test.expectedColumns, printer.Columns) {
|
||||
t.Errorf("[%s]\nexpected:\n%v\nsaw:\n%v\n", test.name, test.expectedColumns, printer.Columns)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
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}`
|
||||
|
||||
const exampleTemplateTwo = `NAME API_VERSION
|
||||
{metadata.name} {apiVersion}`
|
||||
|
||||
func TestNewColumnPrinterFromTemplate(t *testing.T) {
|
||||
tests := []struct {
|
||||
spec string
|
||||
expectedColumns []Column
|
||||
expectErr bool
|
||||
name string
|
||||
}{
|
||||
{
|
||||
spec: "",
|
||||
expectErr: true,
|
||||
name: "empty",
|
||||
},
|
||||
{
|
||||
spec: "invalid",
|
||||
expectErr: true,
|
||||
name: "invalid1",
|
||||
},
|
||||
{
|
||||
spec: "invalid=foobar",
|
||||
expectErr: true,
|
||||
name: "invalid2",
|
||||
},
|
||||
{
|
||||
spec: "invalid,foobar:blah",
|
||||
expectErr: true,
|
||||
name: "invalid3",
|
||||
},
|
||||
{
|
||||
spec: exampleTemplateOne,
|
||||
name: "ok",
|
||||
expectedColumns: []Column{
|
||||
{
|
||||
Header: "NAME",
|
||||
FieldSpec: "{.metadata.name}",
|
||||
},
|
||||
{
|
||||
Header: "API_VERSION",
|
||||
FieldSpec: "{.apiVersion}",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
spec: exampleTemplateTwo,
|
||||
name: "ok-2",
|
||||
expectedColumns: []Column{
|
||||
{
|
||||
Header: "NAME",
|
||||
FieldSpec: "{.metadata.name}",
|
||||
},
|
||||
{
|
||||
Header: "API_VERSION",
|
||||
FieldSpec: "{.apiVersion}",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
reader := bytes.NewBufferString(test.spec)
|
||||
printer, err := NewCustomColumnsPrinterFromTemplate(reader, legacyscheme.Codecs.UniversalDecoder())
|
||||
if test.expectErr {
|
||||
if err == nil {
|
||||
t.Errorf("[%s] unexpected non-error", test.name)
|
||||
}
|
||||
return
|
||||
}
|
||||
if !test.expectErr && err != nil {
|
||||
t.Errorf("[%s] unexpected error: %v", test.name, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(test.expectedColumns, printer.Columns) {
|
||||
t.Errorf("[%s]\nexpected:\n%v\nsaw:\n%v\n", test.name, test.expectedColumns, printer.Columns)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestColumnPrint(t *testing.T) {
|
||||
tests := []struct {
|
||||
columns []Column
|
||||
obj runtime.Object
|
||||
expectedOutput string
|
||||
}{
|
||||
{
|
||||
columns: []Column{
|
||||
{
|
||||
Header: "NAME",
|
||||
FieldSpec: "{.metadata.name}",
|
||||
},
|
||||
},
|
||||
obj: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}},
|
||||
expectedOutput: `NAME
|
||||
foo
|
||||
`,
|
||||
},
|
||||
{
|
||||
columns: []Column{
|
||||
{
|
||||
Header: "NAME",
|
||||
FieldSpec: "{.metadata.name}",
|
||||
},
|
||||
},
|
||||
obj: &v1.PodList{
|
||||
Items: []v1.Pod{
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: "foo"}},
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: "bar"}},
|
||||
},
|
||||
},
|
||||
expectedOutput: `NAME
|
||||
foo
|
||||
bar
|
||||
`,
|
||||
},
|
||||
{
|
||||
columns: []Column{
|
||||
{
|
||||
Header: "NAME",
|
||||
FieldSpec: "{.metadata.name}",
|
||||
},
|
||||
{
|
||||
Header: "API_VERSION",
|
||||
FieldSpec: "{.apiVersion}",
|
||||
},
|
||||
},
|
||||
obj: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}, TypeMeta: metav1.TypeMeta{APIVersion: "baz"}},
|
||||
expectedOutput: `NAME API_VERSION
|
||||
foo baz
|
||||
`,
|
||||
},
|
||||
{
|
||||
columns: []Column{
|
||||
{
|
||||
Header: "NAME",
|
||||
FieldSpec: "{.metadata.name}",
|
||||
},
|
||||
{
|
||||
Header: "API_VERSION",
|
||||
FieldSpec: "{.apiVersion}",
|
||||
},
|
||||
{
|
||||
Header: "NOT_FOUND",
|
||||
FieldSpec: "{.notFound}",
|
||||
},
|
||||
},
|
||||
obj: &v1.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}, TypeMeta: metav1.TypeMeta{APIVersion: "baz"}},
|
||||
expectedOutput: `NAME API_VERSION NOT_FOUND
|
||||
foo baz <none>
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.expectedOutput, func(t *testing.T) {
|
||||
printer := &CustomColumnsPrinter{
|
||||
Columns: test.columns,
|
||||
Decoder: legacyscheme.Codecs.UniversalDecoder(),
|
||||
}
|
||||
buffer := &bytes.Buffer{}
|
||||
if err := printer.PrintObj(test.obj, buffer); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
if buffer.String() != test.expectedOutput {
|
||||
t.Errorf("\nexpected:\n'%s'\nsaw\n'%s'\n", test.expectedOutput, buffer.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// this mimics how resource/get.go calls the customcolumn printer
|
||||
func TestIndividualPrintObjOnExistingTabWriter(t *testing.T) {
|
||||
columns := []Column{
|
||||
{
|
||||
Header: "NAME",
|
||||
FieldSpec: "{.metadata.name}",
|
||||
},
|
||||
{
|
||||
Header: "LONG COLUMN NAME", // name is longer than all values of label1
|
||||
FieldSpec: "{.metadata.labels.label1}",
|
||||
},
|
||||
{
|
||||
Header: "LABEL 2",
|
||||
FieldSpec: "{.metadata.labels.label2}",
|
||||
},
|
||||
}
|
||||
objects := []*v1.Pod{
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: "foo", Labels: map[string]string{"label1": "foo", "label2": "foo"}}},
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: "bar", Labels: map[string]string{"label1": "bar", "label2": "bar"}}},
|
||||
}
|
||||
expectedOutput := `NAME LONG COLUMN NAME LABEL 2
|
||||
foo foo foo
|
||||
bar bar bar
|
||||
`
|
||||
|
||||
buffer := &bytes.Buffer{}
|
||||
tabWriter := GetNewTabWriter(buffer)
|
||||
printer := &CustomColumnsPrinter{
|
||||
Columns: columns,
|
||||
Decoder: legacyscheme.Codecs.UniversalDecoder(),
|
||||
}
|
||||
for _, obj := range objects {
|
||||
if err := printer.PrintObj(obj, tabWriter); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
tabWriter.Flush()
|
||||
if buffer.String() != expectedOutput {
|
||||
t.Errorf("\nexpected:\n'%s'\nsaw\n'%s'\n", expectedOutput, buffer.String())
|
||||
}
|
||||
}
|
32
vendor/k8s.io/kubernetes/pkg/printers/humanreadable.go
generated
vendored
32
vendor/k8s.io/kubernetes/pkg/printers/humanreadable.go
generated
vendored
@ -114,17 +114,25 @@ func (h *HumanReadablePrinter) EnsurePrintHeaders() {
|
||||
// See ValidatePrintHandlerFunc for required method signature.
|
||||
func (h *HumanReadablePrinter) Handler(columns, columnsWithWide []string, printFunc interface{}) error {
|
||||
var columnDefinitions []metav1beta1.TableColumnDefinition
|
||||
for _, column := range columns {
|
||||
for i, column := range columns {
|
||||
format := ""
|
||||
if i == 0 && strings.EqualFold(column, "name") {
|
||||
format = "name"
|
||||
}
|
||||
|
||||
columnDefinitions = append(columnDefinitions, metav1beta1.TableColumnDefinition{
|
||||
Name: column,
|
||||
Type: "string",
|
||||
Name: column,
|
||||
Description: column,
|
||||
Type: "string",
|
||||
Format: format,
|
||||
})
|
||||
}
|
||||
for _, column := range columnsWithWide {
|
||||
columnDefinitions = append(columnDefinitions, metav1beta1.TableColumnDefinition{
|
||||
Name: column,
|
||||
Type: "string",
|
||||
Priority: 1,
|
||||
Name: column,
|
||||
Description: column,
|
||||
Type: "string",
|
||||
Priority: 1,
|
||||
})
|
||||
}
|
||||
|
||||
@ -363,6 +371,11 @@ func PrintTable(table *metav1beta1.Table, output io.Writer, options PrintOptions
|
||||
for _, row := range table.Rows {
|
||||
first := true
|
||||
for i, cell := range row.Cells {
|
||||
if i >= len(table.ColumnDefinitions) {
|
||||
// https://issue.k8s.io/66379
|
||||
// don't panic in case of bad output from the server, with more cells than column definitions
|
||||
break
|
||||
}
|
||||
column := table.ColumnDefinitions[i]
|
||||
if !options.Wide && column.Priority != 0 {
|
||||
continue
|
||||
@ -631,6 +644,13 @@ func (h *HumanReadablePrinter) legacyPrinterToTable(obj runtime.Object, handler
|
||||
args := []reflect.Value{reflect.ValueOf(obj), reflect.ValueOf(buf), reflect.ValueOf(options)}
|
||||
|
||||
if meta.IsListType(obj) {
|
||||
listInterface, ok := obj.(metav1.ListInterface)
|
||||
if ok {
|
||||
table.ListMeta.SelfLink = listInterface.GetSelfLink()
|
||||
table.ListMeta.ResourceVersion = listInterface.GetResourceVersion()
|
||||
table.ListMeta.Continue = listInterface.GetContinue()
|
||||
}
|
||||
|
||||
// TODO: this uses more memory than it has to, as we refactor printers we should remove the need
|
||||
// for this.
|
||||
args[0] = reflect.ValueOf(obj)
|
||||
|
34
vendor/k8s.io/kubernetes/pkg/printers/interface.go
generated
vendored
34
vendor/k8s.io/kubernetes/pkg/printers/interface.go
generated
vendored
@ -17,7 +17,6 @@ limitations under the License.
|
||||
package printers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@ -58,36 +57,3 @@ type PrintOptions struct {
|
||||
// indicates if it is OK to ignore missing keys for rendering an output template.
|
||||
AllowMissingKeys bool
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
117
vendor/k8s.io/kubernetes/pkg/printers/internalversion/BUILD
generated
vendored
117
vendor/k8s.io/kubernetes/pkg/printers/internalversion/BUILD
generated
vendored
@ -9,7 +9,6 @@ load(
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"describe_test.go",
|
||||
"printers_test.go",
|
||||
"sorted_resource_name_list_test.go",
|
||||
],
|
||||
@ -20,99 +19,89 @@ go_test(
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/autoscaling:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/coordination:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/networking:go_default_library",
|
||||
"//pkg/apis/policy:go_default_library",
|
||||
"//pkg/apis/scheduling:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||
"//pkg/kubectl/genericclioptions/printers:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//pkg/util/pointer:go_default_library",
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality: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/unstructured:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1: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/serializer/yaml:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/yaml:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
|
||||
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/printers:go_default_library",
|
||||
"//vendor/sigs.k8s.io/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"describe.go",
|
||||
"import_known_versions.go",
|
||||
"printers.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/printers/internalversion",
|
||||
deps = [
|
||||
"//pkg/api/events:go_default_library",
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/api/ref:go_default_library",
|
||||
"//pkg/api/resource:go_default_library",
|
||||
"//pkg/apis/apps:go_default_library",
|
||||
"//pkg/apis/apps/install:go_default_library",
|
||||
"//pkg/apis/authentication/install:go_default_library",
|
||||
"//pkg/apis/authorization/install:go_default_library",
|
||||
"//pkg/apis/autoscaling:go_default_library",
|
||||
"//pkg/apis/autoscaling/install:go_default_library",
|
||||
"//pkg/apis/batch:go_default_library",
|
||||
"//pkg/apis/batch/install:go_default_library",
|
||||
"//pkg/apis/certificates:go_default_library",
|
||||
"//pkg/apis/certificates/install:go_default_library",
|
||||
"//pkg/apis/coordination:go_default_library",
|
||||
"//pkg/apis/coordination/install:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/helper:go_default_library",
|
||||
"//pkg/apis/core/helper/qos:go_default_library",
|
||||
"//pkg/apis/core/install:go_default_library",
|
||||
"//pkg/apis/events/install:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/extensions/install:go_default_library",
|
||||
"//pkg/apis/networking:go_default_library",
|
||||
"//pkg/apis/policy:go_default_library",
|
||||
"//pkg/apis/policy/install:go_default_library",
|
||||
"//pkg/apis/rbac:go_default_library",
|
||||
"//pkg/apis/rbac/v1:go_default_library",
|
||||
"//pkg/apis/rbac/install:go_default_library",
|
||||
"//pkg/apis/scheduling:go_default_library",
|
||||
"//pkg/apis/scheduling/install:go_default_library",
|
||||
"//pkg/apis/settings/install:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/apis/storage/install:go_default_library",
|
||||
"//pkg/apis/storage/util:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/typed/core/internalversion:go_default_library",
|
||||
"//pkg/controller/deployment/util:go_default_library",
|
||||
"//pkg/fieldpath:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//pkg/registry/rbac/validation:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
"//pkg/util/slice:go_default_library",
|
||||
"//vendor/github.com/fatih/camelcase:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/autoscaling/v2beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/rbac/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/rbac/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/storage/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/errors: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/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1: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/runtime: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/util/duration:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/client-go/dynamic:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/batch/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/coordination/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/rbac/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/scheduling/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/storage/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/duration:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
4023
vendor/k8s.io/kubernetes/pkg/printers/internalversion/describe.go
generated
vendored
4023
vendor/k8s.io/kubernetes/pkg/printers/internalversion/describe.go
generated
vendored
File diff suppressed because it is too large
Load Diff
2718
vendor/k8s.io/kubernetes/pkg/printers/internalversion/describe_test.go
generated
vendored
2718
vendor/k8s.io/kubernetes/pkg/printers/internalversion/describe_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
37
vendor/k8s.io/kubernetes/pkg/printers/internalversion/import_known_versions.go
generated
vendored
Normal file
37
vendor/k8s.io/kubernetes/pkg/printers/internalversion/import_known_versions.go
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright 2016 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 internalversion
|
||||
|
||||
// These imports are the API groups the client will support.
|
||||
// TODO: Remove these manual install once we don't need legacy scheme in get comman
|
||||
import (
|
||||
_ "k8s.io/kubernetes/pkg/apis/apps/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/authentication/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/authorization/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/autoscaling/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/batch/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/certificates/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/coordination/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/events/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/extensions/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/policy/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/rbac/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/scheduling/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/settings/install"
|
||||
_ "k8s.io/kubernetes/pkg/apis/storage/install"
|
||||
)
|
469
vendor/k8s.io/kubernetes/pkg/printers/internalversion/printers.go
generated
vendored
469
vendor/k8s.io/kubernetes/pkg/printers/internalversion/printers.go
generated
vendored
@ -19,7 +19,6 @@ package internalversion
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"sort"
|
||||
"strconv"
|
||||
@ -31,9 +30,12 @@ import (
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
certificatesv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
coordinationv1beta1 "k8s.io/api/coordination/v1beta1"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
policyv1beta1 "k8s.io/api/policy/v1beta1"
|
||||
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
|
||||
schedulingv1beta1 "k8s.io/api/scheduling/v1beta1"
|
||||
storagev1 "k8s.io/api/storage/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -43,17 +45,18 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/duration"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/kubernetes/pkg/api/events"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/certificates"
|
||||
"k8s.io/kubernetes/pkg/apis/coordination"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/networking"
|
||||
"k8s.io/kubernetes/pkg/apis/policy"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/apis/scheduling"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
storageutil "k8s.io/kubernetes/pkg/apis/storage/util"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
@ -82,6 +85,8 @@ func AddHandlers(h printers.PrintHandler) {
|
||||
{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"]},
|
||||
{Name: "Nominated Node", Type: "string", Priority: 1, Description: apiv1.PodStatus{}.SwaggerDoc()["nominatedNodeName"]},
|
||||
{Name: "Readiness Gates", Type: "string", Priority: 1, Description: apiv1.PodSpec{}.SwaggerDoc()["readinessGates"]},
|
||||
}
|
||||
h.TableHandler(podColumnDefinitions, printPodList)
|
||||
h.TableHandler(podColumnDefinitions, printPod)
|
||||
@ -149,8 +154,8 @@ func AddHandlers(h printers.PrintHandler) {
|
||||
|
||||
jobColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "Desired", Type: "integer", Description: batchv1.JobSpec{}.SwaggerDoc()["completions"]},
|
||||
{Name: "Successful", Type: "integer", Description: batchv1.JobStatus{}.SwaggerDoc()["succeeded"]},
|
||||
{Name: "Completions", Type: "string", Description: batchv1.JobStatus{}.SwaggerDoc()["succeeded"]},
|
||||
{Name: "Duration", Type: "string", Description: "Time required to complete the job."},
|
||||
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||
{Name: "Containers", Type: "string", Priority: 1, Description: "Names of each container in the template."},
|
||||
{Name: "Images", Type: "string", Priority: 1, Description: "Images referenced by each container in the template."},
|
||||
@ -198,8 +203,7 @@ func AddHandlers(h printers.PrintHandler) {
|
||||
|
||||
statefulSetColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "Desired", Type: "string", Description: appsv1beta1.StatefulSetSpec{}.SwaggerDoc()["replicas"]},
|
||||
{Name: "Current", Type: "string", Description: appsv1beta1.StatefulSetStatus{}.SwaggerDoc()["replicas"]},
|
||||
{Name: "Ready", Type: "string", Description: "Number of the pod with ready state"},
|
||||
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||
{Name: "Containers", Type: "string", Priority: 1, Description: "Names of each container in the template."},
|
||||
{Name: "Images", Type: "string", Priority: 1, Description: "Images referenced by each container in the template."},
|
||||
@ -233,15 +237,15 @@ func AddHandlers(h printers.PrintHandler) {
|
||||
|
||||
eventColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Last Seen", Type: "string", Description: apiv1.Event{}.SwaggerDoc()["lastTimestamp"]},
|
||||
{Name: "First Seen", Type: "string", Description: apiv1.Event{}.SwaggerDoc()["firstTimestamp"]},
|
||||
{Name: "Count", Type: "string", Description: apiv1.Event{}.SwaggerDoc()["count"]},
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "Kind", Type: "string", Description: apiv1.Event{}.InvolvedObject.SwaggerDoc()["kind"]},
|
||||
{Name: "Subobject", Type: "string", Description: apiv1.Event{}.InvolvedObject.SwaggerDoc()["fieldPath"]},
|
||||
{Name: "Type", Type: "string", Description: apiv1.Event{}.SwaggerDoc()["type"]},
|
||||
{Name: "Reason", Type: "string", Description: apiv1.Event{}.SwaggerDoc()["reason"]},
|
||||
{Name: "Source", Type: "string", Description: apiv1.Event{}.SwaggerDoc()["source"]},
|
||||
{Name: "Kind", Type: "string", Description: apiv1.Event{}.InvolvedObject.SwaggerDoc()["kind"]},
|
||||
{Name: "Source", Type: "string", Priority: 1, Description: apiv1.Event{}.SwaggerDoc()["source"]},
|
||||
{Name: "Message", Type: "string", Description: apiv1.Event{}.SwaggerDoc()["message"]},
|
||||
{Name: "Subobject", Type: "string", Priority: 1, Description: apiv1.Event{}.InvolvedObject.SwaggerDoc()["fieldPath"]},
|
||||
{Name: "First Seen", Type: "string", Priority: 1, Description: apiv1.Event{}.SwaggerDoc()["firstTimestamp"]},
|
||||
{Name: "Count", Type: "string", Priority: 1, Description: apiv1.Event{}.SwaggerDoc()["count"]},
|
||||
{Name: "Name", Type: "string", Priority: 1, Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
}
|
||||
h.TableHandler(eventColumnDefinitions, printEvent)
|
||||
h.TableHandler(eventColumnDefinitions, printEventList)
|
||||
@ -308,8 +312,7 @@ func AddHandlers(h printers.PrintHandler) {
|
||||
|
||||
deploymentColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "Desired", Type: "string", Description: extensionsv1beta1.DeploymentSpec{}.SwaggerDoc()["replicas"]},
|
||||
{Name: "Current", Type: "string", Description: extensionsv1beta1.DeploymentStatus{}.SwaggerDoc()["replicas"]},
|
||||
{Name: "Ready", Type: "string", Description: "Number of the pod with ready state"},
|
||||
{Name: "Up-to-date", Type: "string", Description: extensionsv1beta1.DeploymentStatus{}.SwaggerDoc()["updatedReplicas"]},
|
||||
{Name: "Available", Type: "string", Description: extensionsv1beta1.DeploymentStatus{}.SwaggerDoc()["availableReplicas"]},
|
||||
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||
@ -342,14 +345,14 @@ func AddHandlers(h printers.PrintHandler) {
|
||||
|
||||
podSecurityPolicyColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "Priv", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["privileged"]},
|
||||
{Name: "Caps", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["allowedCapabilities"]},
|
||||
{Name: "SELinux", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["seLinux"]},
|
||||
{Name: "RunAsUser", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["runAsUser"]},
|
||||
{Name: "FsGroup", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["fsGroup"]},
|
||||
{Name: "SupGroup", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["supplementalGroups"]},
|
||||
{Name: "ReadOnlyRootFs", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["readOnlyRootFilesystem"]},
|
||||
{Name: "Volumes", Type: "string", Description: extensionsv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["volumes"]},
|
||||
{Name: "Priv", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["privileged"]},
|
||||
{Name: "Caps", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["allowedCapabilities"]},
|
||||
{Name: "SELinux", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["seLinux"]},
|
||||
{Name: "RunAsUser", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["runAsUser"]},
|
||||
{Name: "FsGroup", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["fsGroup"]},
|
||||
{Name: "SupGroup", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["supplementalGroups"]},
|
||||
{Name: "ReadOnlyRootFs", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["readOnlyRootFilesystem"]},
|
||||
{Name: "Volumes", Type: "string", Description: policyv1beta1.PodSecurityPolicySpec{}.SwaggerDoc()["volumes"]},
|
||||
}
|
||||
h.TableHandler(podSecurityPolicyColumnDefinitions, printPodSecurityPolicy)
|
||||
h.TableHandler(podSecurityPolicyColumnDefinitions, printPodSecurityPolicyList)
|
||||
@ -393,6 +396,14 @@ func AddHandlers(h printers.PrintHandler) {
|
||||
h.TableHandler(certificateSigningRequestColumnDefinitions, printCertificateSigningRequest)
|
||||
h.TableHandler(certificateSigningRequestColumnDefinitions, printCertificateSigningRequestList)
|
||||
|
||||
leaseColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "Holder", Type: "string", Description: coordinationv1beta1.LeaseSpec{}.SwaggerDoc()["holderIdentity"]},
|
||||
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||
}
|
||||
h.TableHandler(leaseColumnDefinitions, printLease)
|
||||
h.TableHandler(leaseColumnDefinitions, printLeaseList)
|
||||
|
||||
storageClassColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "Provisioner", Type: "string", Description: storagev1.StorageClass{}.SwaggerDoc()["provisioner"]},
|
||||
@ -419,6 +430,24 @@ func AddHandlers(h printers.PrintHandler) {
|
||||
h.TableHandler(controllerRevisionColumnDefinition, printControllerRevision)
|
||||
h.TableHandler(controllerRevisionColumnDefinition, printControllerRevisionList)
|
||||
|
||||
resorceQuotaColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||
{Name: "Request", Type: "string", Description: "Request represents a minimum amount of cpu/memory that a container may consume."},
|
||||
{Name: "Limit", Type: "string", Description: "Limits control the maximum amount of cpu/memory that a container may use independent of contention on the node."},
|
||||
}
|
||||
h.TableHandler(resorceQuotaColumnDefinitions, printResourceQuota)
|
||||
h.TableHandler(resorceQuotaColumnDefinitions, printResourceQuotaList)
|
||||
|
||||
priorityClassColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
|
||||
{Name: "Value", Type: "integer", Description: schedulingv1beta1.PriorityClass{}.SwaggerDoc()["value"]},
|
||||
{Name: "Global-Default", Type: "boolean", Description: schedulingv1beta1.PriorityClass{}.SwaggerDoc()["globalDefault"]},
|
||||
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
|
||||
}
|
||||
h.TableHandler(priorityClassColumnDefinitions, printPriorityClass)
|
||||
h.TableHandler(priorityClassColumnDefinitions, printPriorityClassList)
|
||||
|
||||
AddDefaultHandlers(h)
|
||||
}
|
||||
|
||||
@ -457,7 +486,7 @@ func printObjectMeta(obj runtime.Object, options printers.PrintOptions) ([]metav
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
row.Cells = append(row.Cells, m.GetName(), translateTimestamp(m.GetCreationTimestamp()))
|
||||
row.Cells = append(row.Cells, m.GetName(), translateTimestampSince(m.GetCreationTimestamp()))
|
||||
rows = append(rows, row)
|
||||
return rows, nil
|
||||
}
|
||||
@ -473,19 +502,33 @@ func formatEndpoints(endpoints *api.Endpoints, ports sets.String) string {
|
||||
count := 0
|
||||
for i := range endpoints.Subsets {
|
||||
ss := &endpoints.Subsets[i]
|
||||
for i := range ss.Ports {
|
||||
port := &ss.Ports[i]
|
||||
if ports == nil || ports.Has(port.Name) {
|
||||
for i := range ss.Addresses {
|
||||
if len(list) == max {
|
||||
more = true
|
||||
if len(ss.Ports) == 0 {
|
||||
// It's possible to have headless services with no ports.
|
||||
for i := range ss.Addresses {
|
||||
if len(list) == max {
|
||||
more = true
|
||||
}
|
||||
if !more {
|
||||
list = append(list, ss.Addresses[i].IP)
|
||||
}
|
||||
count++
|
||||
}
|
||||
} else {
|
||||
// "Normal" services with ports defined.
|
||||
for i := range ss.Ports {
|
||||
port := &ss.Ports[i]
|
||||
if ports == nil || ports.Has(port.Name) {
|
||||
for i := range ss.Addresses {
|
||||
if len(list) == max {
|
||||
more = true
|
||||
}
|
||||
addr := &ss.Addresses[i]
|
||||
if !more {
|
||||
hostPort := net.JoinHostPort(addr.IP, strconv.Itoa(int(port.Port)))
|
||||
list = append(list, hostPort)
|
||||
}
|
||||
count++
|
||||
}
|
||||
addr := &ss.Addresses[i]
|
||||
if !more {
|
||||
hostPort := net.JoinHostPort(addr.IP, strconv.Itoa(int(port.Port)))
|
||||
list = append(list, hostPort)
|
||||
}
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -497,14 +540,24 @@ func formatEndpoints(endpoints *api.Endpoints, ports sets.String) string {
|
||||
return ret
|
||||
}
|
||||
|
||||
// translateTimestamp returns the elapsed time since timestamp in
|
||||
// translateTimestampSince returns the elapsed time since timestamp in
|
||||
// human-readable approximation.
|
||||
func translateTimestamp(timestamp metav1.Time) string {
|
||||
func translateTimestampSince(timestamp metav1.Time) string {
|
||||
if timestamp.IsZero() {
|
||||
return "<unknown>"
|
||||
}
|
||||
|
||||
return duration.ShortHumanDuration(time.Since(timestamp.Time))
|
||||
return duration.HumanDuration(time.Since(timestamp.Time))
|
||||
}
|
||||
|
||||
// translateTimestampUntil returns the elapsed time until timestamp in
|
||||
// human-readable approximation.
|
||||
func translateTimestampUntil(timestamp metav1.Time) string {
|
||||
if timestamp.IsZero() {
|
||||
return "<unknown>"
|
||||
}
|
||||
|
||||
return duration.HumanDuration(time.Until(timestamp.Time))
|
||||
}
|
||||
|
||||
var (
|
||||
@ -608,21 +661,39 @@ func printPod(pod *api.Pod, options printers.PrintOptions) ([]metav1beta1.TableR
|
||||
reason = "Terminating"
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, pod.Name, fmt.Sprintf("%d/%d", readyContainers, totalContainers), reason, int64(restarts), translateTimestamp(pod.CreationTimestamp))
|
||||
|
||||
row.Cells = append(row.Cells, pod.Name, fmt.Sprintf("%d/%d", readyContainers, totalContainers), reason, int64(restarts), translateTimestampSince(pod.CreationTimestamp))
|
||||
if options.Wide {
|
||||
nodeName := pod.Spec.NodeName
|
||||
nominatedNodeName := pod.Status.NominatedNodeName
|
||||
podIP := pod.Status.PodIP
|
||||
|
||||
if podIP == "" {
|
||||
podIP = "<none>"
|
||||
}
|
||||
if nodeName == "" {
|
||||
nodeName = "<none>"
|
||||
}
|
||||
row.Cells = append(row.Cells, podIP, nodeName)
|
||||
if len(pod.Status.NominatedNodeName) > 0 {
|
||||
row.Cells = append(row.Cells, pod.Status.NominatedNodeName)
|
||||
if nominatedNodeName == "" {
|
||||
nominatedNodeName = "<none>"
|
||||
}
|
||||
|
||||
readinessGates := "<none>"
|
||||
if len(pod.Spec.ReadinessGates) > 0 {
|
||||
trueConditions := 0
|
||||
for _, readinessGate := range pod.Spec.ReadinessGates {
|
||||
conditionType := readinessGate.ConditionType
|
||||
for _, condition := range pod.Status.Conditions {
|
||||
if condition.Type == conditionType {
|
||||
if condition.Status == api.ConditionTrue {
|
||||
trueConditions += 1
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
readinessGates = fmt.Sprintf("%d/%d", trueConditions, len(pod.Spec.ReadinessGates))
|
||||
}
|
||||
row.Cells = append(row.Cells, podIP, nodeName, nominatedNodeName, readinessGates)
|
||||
}
|
||||
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
@ -668,7 +739,7 @@ func printPodDisruptionBudget(obj *policy.PodDisruptionBudget, options printers.
|
||||
maxUnavailable = "N/A"
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, minAvailable, maxUnavailable, int64(obj.Status.PodDisruptionsAllowed), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, minAvailable, maxUnavailable, int64(obj.Status.PodDisruptionsAllowed), translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -694,7 +765,7 @@ func printReplicationController(obj *api.ReplicationController, options printers
|
||||
currentReplicas := obj.Status.Replicas
|
||||
readyReplicas := obj.Status.ReadyReplicas
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, int64(desiredReplicas), int64(currentReplicas), int64(readyReplicas), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, int64(desiredReplicas), int64(currentReplicas), int64(readyReplicas), translateTimestampSince(obj.CreationTimestamp))
|
||||
if options.Wide {
|
||||
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
|
||||
row.Cells = append(row.Cells, names, images, labels.FormatLabels(obj.Spec.Selector))
|
||||
@ -714,7 +785,7 @@ func printReplicationControllerList(list *api.ReplicationControllerList, options
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func printReplicaSet(obj *extensions.ReplicaSet, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
func printReplicaSet(obj *apps.ReplicaSet, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
@ -723,7 +794,7 @@ func printReplicaSet(obj *extensions.ReplicaSet, options printers.PrintOptions)
|
||||
currentReplicas := obj.Status.Replicas
|
||||
readyReplicas := obj.Status.ReadyReplicas
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, int64(desiredReplicas), int64(currentReplicas), int64(readyReplicas), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, int64(desiredReplicas), int64(currentReplicas), int64(readyReplicas), translateTimestampSince(obj.CreationTimestamp))
|
||||
if options.Wide {
|
||||
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
|
||||
row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector))
|
||||
@ -731,7 +802,7 @@ func printReplicaSet(obj *extensions.ReplicaSet, options printers.PrintOptions)
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
func printReplicaSetList(list *extensions.ReplicaSetList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
func printReplicaSetList(list *apps.ReplicaSetList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
rows := make([]metav1beta1.TableRow, 0, len(list.Items))
|
||||
for i := range list.Items {
|
||||
r, err := printReplicaSet(&list.Items[i], options)
|
||||
@ -750,12 +821,28 @@ func printJob(obj *batch.Job, options printers.PrintOptions) ([]metav1beta1.Tabl
|
||||
|
||||
var completions string
|
||||
if obj.Spec.Completions != nil {
|
||||
completions = strconv.Itoa(int(*obj.Spec.Completions))
|
||||
completions = fmt.Sprintf("%d/%d", obj.Status.Succeeded, *obj.Spec.Completions)
|
||||
} else {
|
||||
completions = "<none>"
|
||||
parallelism := int32(0)
|
||||
if obj.Spec.Parallelism != nil {
|
||||
parallelism = *obj.Spec.Parallelism
|
||||
}
|
||||
if parallelism > 1 {
|
||||
completions = fmt.Sprintf("%d/1 of %d", obj.Status.Succeeded, parallelism)
|
||||
} else {
|
||||
completions = fmt.Sprintf("%d/1", obj.Status.Succeeded)
|
||||
}
|
||||
}
|
||||
var jobDuration string
|
||||
switch {
|
||||
case obj.Status.StartTime == nil:
|
||||
case obj.Status.CompletionTime == nil:
|
||||
jobDuration = duration.HumanDuration(time.Now().Sub(obj.Status.StartTime.Time))
|
||||
default:
|
||||
jobDuration = duration.HumanDuration(obj.Status.CompletionTime.Sub(obj.Status.StartTime.Time))
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, completions, int64(obj.Status.Succeeded), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, completions, jobDuration, translateTimestampSince(obj.CreationTimestamp))
|
||||
if options.Wide {
|
||||
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
|
||||
row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector))
|
||||
@ -782,10 +869,10 @@ func printCronJob(obj *batch.CronJob, options printers.PrintOptions) ([]metav1be
|
||||
|
||||
lastScheduleTime := "<none>"
|
||||
if obj.Status.LastScheduleTime != nil {
|
||||
lastScheduleTime = translateTimestamp(*obj.Status.LastScheduleTime)
|
||||
lastScheduleTime = translateTimestampSince(*obj.Status.LastScheduleTime)
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, obj.Spec.Schedule, printBoolPtr(obj.Spec.Suspend), int64(len(obj.Status.Active)), lastScheduleTime, translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, obj.Spec.Schedule, printBoolPtr(obj.Spec.Suspend), int64(len(obj.Status.Active)), lastScheduleTime, translateTimestampSince(obj.CreationTimestamp))
|
||||
if options.Wide {
|
||||
names, images := layoutContainerCells(obj.Spec.JobTemplate.Spec.Template.Spec.Containers)
|
||||
row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.JobTemplate.Spec.Selector))
|
||||
@ -884,7 +971,7 @@ func printService(obj *api.Service, options printers.PrintOptions) ([]metav1beta
|
||||
svcPorts = "<none>"
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, string(svcType), internalIP, externalIP, svcPorts, translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, string(svcType), internalIP, externalIP, svcPorts, translateTimestampSince(obj.CreationTimestamp))
|
||||
if options.Wide {
|
||||
row.Cells = append(row.Cells, labels.FormatLabels(obj.Spec.Selector))
|
||||
}
|
||||
@ -948,7 +1035,7 @@ func printIngress(obj *extensions.Ingress, options printers.PrintOptions) ([]met
|
||||
hosts := formatHosts(obj.Spec.Rules)
|
||||
address := loadBalancerStatusStringer(obj.Status.LoadBalancer, options.Wide)
|
||||
ports := formatPorts(obj.Spec.TLS)
|
||||
createTime := translateTimestamp(obj.CreationTimestamp)
|
||||
createTime := translateTimestampSince(obj.CreationTimestamp)
|
||||
row.Cells = append(row.Cells, obj.Name, hosts, address, ports, createTime)
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
@ -970,9 +1057,9 @@ func printStatefulSet(obj *apps.StatefulSet, options printers.PrintOptions) ([]m
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
desiredReplicas := obj.Spec.Replicas
|
||||
currentReplicas := obj.Status.Replicas
|
||||
createTime := translateTimestamp(obj.CreationTimestamp)
|
||||
row.Cells = append(row.Cells, obj.Name, int64(desiredReplicas), int64(currentReplicas), createTime)
|
||||
readyReplicas := obj.Status.ReadyReplicas
|
||||
createTime := translateTimestampSince(obj.CreationTimestamp)
|
||||
row.Cells = append(row.Cells, obj.Name, fmt.Sprintf("%d/%d", int64(readyReplicas), int64(desiredReplicas)), createTime)
|
||||
if options.Wide {
|
||||
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
|
||||
row.Cells = append(row.Cells, names, images)
|
||||
@ -992,7 +1079,7 @@ func printStatefulSetList(list *apps.StatefulSetList, options printers.PrintOpti
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func printDaemonSet(obj *extensions.DaemonSet, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
func printDaemonSet(obj *apps.DaemonSet, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
@ -1003,7 +1090,7 @@ func printDaemonSet(obj *extensions.DaemonSet, options printers.PrintOptions) ([
|
||||
numberUpdated := obj.Status.UpdatedNumberScheduled
|
||||
numberAvailable := obj.Status.NumberAvailable
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, int64(desiredScheduled), int64(currentScheduled), int64(numberReady), int64(numberUpdated), int64(numberAvailable), labels.FormatLabels(obj.Spec.Template.Spec.NodeSelector), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, int64(desiredScheduled), int64(currentScheduled), int64(numberReady), int64(numberUpdated), int64(numberAvailable), labels.FormatLabels(obj.Spec.Template.Spec.NodeSelector), translateTimestampSince(obj.CreationTimestamp))
|
||||
if options.Wide {
|
||||
names, images := layoutContainerCells(obj.Spec.Template.Spec.Containers)
|
||||
row.Cells = append(row.Cells, names, images, metav1.FormatLabelSelector(obj.Spec.Selector))
|
||||
@ -1011,7 +1098,7 @@ func printDaemonSet(obj *extensions.DaemonSet, options printers.PrintOptions) ([
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
func printDaemonSetList(list *extensions.DaemonSetList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
func printDaemonSetList(list *apps.DaemonSetList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
rows := make([]metav1beta1.TableRow, 0, len(list.Items))
|
||||
for i := range list.Items {
|
||||
r, err := printDaemonSet(&list.Items[i], options)
|
||||
@ -1027,7 +1114,7 @@ func printEndpoints(obj *api.Endpoints, options printers.PrintOptions) ([]metav1
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
row.Cells = append(row.Cells, obj.Name, formatEndpoints(obj, nil), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, formatEndpoints(obj, nil), translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -1047,7 +1134,7 @@ func printNamespace(obj *api.Namespace, options printers.PrintOptions) ([]metav1
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
row.Cells = append(row.Cells, obj.Name, string(obj.Status.Phase), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, string(obj.Status.Phase), translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -1067,7 +1154,7 @@ func printSecret(obj *api.Secret, options printers.PrintOptions) ([]metav1beta1.
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
row.Cells = append(row.Cells, obj.Name, string(obj.Type), int64(len(obj.Data)), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, string(obj.Type), int64(len(obj.Data)), translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -1087,7 +1174,7 @@ func printServiceAccount(obj *api.ServiceAccount, options printers.PrintOptions)
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
row.Cells = append(row.Cells, obj.Name, int64(len(obj.Secrets)), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, int64(len(obj.Secrets)), translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -1136,7 +1223,7 @@ func printNode(obj *api.Node, options printers.PrintOptions) ([]metav1beta1.Tabl
|
||||
roles = "<none>"
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, strings.Join(status, ","), roles, translateTimestamp(obj.CreationTimestamp), obj.Status.NodeInfo.KubeletVersion)
|
||||
row.Cells = append(row.Cells, obj.Name, strings.Join(status, ","), roles, translateTimestampSince(obj.CreationTimestamp), obj.Status.NodeInfo.KubeletVersion)
|
||||
if options.Wide {
|
||||
osImage, kernelVersion, crVersion := obj.Status.NodeInfo.OSImage, obj.Status.NodeInfo.KernelVersion, obj.Status.NodeInfo.ContainerRuntimeVersion
|
||||
if osImage == "" {
|
||||
@ -1234,7 +1321,7 @@ func printPersistentVolume(obj *api.PersistentVolume, options printers.PrintOpti
|
||||
row.Cells = append(row.Cells, obj.Name, aSize, modesStr, reclaimPolicyStr,
|
||||
string(phase), claimRefUID, helper.GetPersistentVolumeClass(obj),
|
||||
obj.Status.Reason,
|
||||
translateTimestamp(obj.CreationTimestamp))
|
||||
translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -1269,7 +1356,7 @@ func printPersistentVolumeClaim(obj *api.PersistentVolumeClaim, options printers
|
||||
capacity = storage.String()
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, string(phase), obj.Spec.VolumeName, capacity, accessModes, helper.GetPersistentVolumeClaimClass(obj), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, string(phase), obj.Spec.VolumeName, capacity, accessModes, helper.GetPersistentVolumeClaimClass(obj), translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -1290,25 +1377,42 @@ func printEvent(obj *api.Event, options printers.PrintOptions) ([]metav1beta1.Ta
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
// While watching event, we should print absolute time.
|
||||
var FirstTimestamp, LastTimestamp string
|
||||
var firstTimestamp, lastTimestamp string
|
||||
if options.AbsoluteTimestamps {
|
||||
FirstTimestamp = obj.FirstTimestamp.String()
|
||||
LastTimestamp = obj.LastTimestamp.String()
|
||||
firstTimestamp = obj.FirstTimestamp.String()
|
||||
lastTimestamp = obj.LastTimestamp.String()
|
||||
} else {
|
||||
FirstTimestamp = translateTimestamp(obj.FirstTimestamp)
|
||||
LastTimestamp = translateTimestamp(obj.LastTimestamp)
|
||||
firstTimestamp = translateTimestampSince(obj.FirstTimestamp)
|
||||
lastTimestamp = translateTimestampSince(obj.LastTimestamp)
|
||||
}
|
||||
if options.Wide {
|
||||
row.Cells = append(row.Cells,
|
||||
lastTimestamp,
|
||||
obj.Type,
|
||||
obj.Reason,
|
||||
obj.InvolvedObject.Kind,
|
||||
formatEventSource(obj.Source),
|
||||
strings.TrimSpace(obj.Message),
|
||||
obj.InvolvedObject.FieldPath,
|
||||
firstTimestamp,
|
||||
int64(obj.Count),
|
||||
obj.Name,
|
||||
)
|
||||
} else {
|
||||
row.Cells = append(row.Cells,
|
||||
lastTimestamp,
|
||||
obj.Type,
|
||||
obj.Reason,
|
||||
obj.InvolvedObject.Kind,
|
||||
strings.TrimSpace(obj.Message),
|
||||
)
|
||||
}
|
||||
row.Cells = append(row.Cells, LastTimestamp, FirstTimestamp,
|
||||
int64(obj.Count), obj.Name, obj.InvolvedObject.Kind,
|
||||
obj.InvolvedObject.FieldPath, obj.Type, obj.Reason,
|
||||
formatEventSource(obj.Source), obj.Message)
|
||||
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
// Sorts and prints the EventList in a human-friendly format.
|
||||
func printEventList(list *api.EventList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
sort.Sort(events.SortableEvents(list.Items))
|
||||
rows := make([]metav1beta1.TableRow, 0, len(list.Items))
|
||||
for i := range list.Items {
|
||||
r, err := printEvent(&list.Items[i], options)
|
||||
@ -1325,7 +1429,7 @@ func printRoleBinding(obj *rbac.RoleBinding, options printers.PrintOptions) ([]m
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, translateTimestampSince(obj.CreationTimestamp))
|
||||
if options.Wide {
|
||||
roleRef := fmt.Sprintf("%s/%s", obj.RoleRef.Kind, obj.RoleRef.Name)
|
||||
users, groups, sas, _ := rbac.SubjectsStrings(obj.Subjects)
|
||||
@ -1352,7 +1456,7 @@ func printClusterRoleBinding(obj *rbac.ClusterRoleBinding, options printers.Prin
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, obj.Name, translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, translateTimestampSince(obj.CreationTimestamp))
|
||||
if options.Wide {
|
||||
roleRef := fmt.Sprintf("%s/%s", obj.RoleRef.Kind, obj.RoleRef.Name)
|
||||
users, groups, sas, _ := rbac.SubjectsStrings(obj.Subjects)
|
||||
@ -1382,7 +1486,7 @@ func printCertificateSigningRequest(obj *certificates.CertificateSigningRequest,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
row.Cells = append(row.Cells, obj.Name, translateTimestamp(obj.CreationTimestamp), obj.Spec.Username, status)
|
||||
row.Cells = append(row.Cells, obj.Name, translateTimestampSince(obj.CreationTimestamp), obj.Spec.Username, status)
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -1460,29 +1564,22 @@ func printComponentStatusList(list *api.ComponentStatusList, options printers.Pr
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func truncate(str string, maxLen int) string {
|
||||
if len(str) > maxLen {
|
||||
return str[0:maxLen] + "..."
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func printDeployment(obj *extensions.Deployment, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
func printDeployment(obj *apps.Deployment, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
desiredReplicas := obj.Spec.Replicas
|
||||
currentReplicas := obj.Status.Replicas
|
||||
updatedReplicas := obj.Status.UpdatedReplicas
|
||||
readyReplicas := obj.Status.ReadyReplicas
|
||||
availableReplicas := obj.Status.AvailableReplicas
|
||||
age := translateTimestamp(obj.CreationTimestamp)
|
||||
age := translateTimestampSince(obj.CreationTimestamp)
|
||||
containers := obj.Spec.Template.Spec.Containers
|
||||
selector, err := metav1.LabelSelectorAsSelector(obj.Spec.Selector)
|
||||
if err != nil {
|
||||
// this shouldn't happen if LabelSelector passed validation
|
||||
return nil, err
|
||||
}
|
||||
row.Cells = append(row.Cells, obj.Name, int64(desiredReplicas), int64(currentReplicas), int64(updatedReplicas), int64(availableReplicas), age)
|
||||
row.Cells = append(row.Cells, obj.Name, fmt.Sprintf("%d/%d", int64(readyReplicas), int64(desiredReplicas)), int64(updatedReplicas), int64(availableReplicas), age)
|
||||
if options.Wide {
|
||||
containers, images := layoutContainerCells(containers)
|
||||
row.Cells = append(row.Cells, containers, images, selector.String())
|
||||
@ -1490,7 +1587,7 @@ func printDeployment(obj *extensions.Deployment, options printers.PrintOptions)
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
func printDeploymentList(list *extensions.DeploymentList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
func printDeploymentList(list *apps.DeploymentList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
rows := make([]metav1beta1.TableRow, 0, len(list.Items))
|
||||
for i := range list.Items {
|
||||
r, err := printDeployment(&list.Items[i], options)
|
||||
@ -1513,47 +1610,47 @@ func formatHPAMetrics(specs []autoscaling.MetricSpec, statuses []autoscaling.Met
|
||||
for i, spec := range specs {
|
||||
switch spec.Type {
|
||||
case autoscaling.ExternalMetricSourceType:
|
||||
if spec.External.TargetAverageValue != nil {
|
||||
if spec.External.Target.AverageValue != nil {
|
||||
current := "<unknown>"
|
||||
if len(statuses) > i && statuses[i].External != nil && statuses[i].External.CurrentAverageValue != nil {
|
||||
current = statuses[i].External.CurrentAverageValue.String()
|
||||
if len(statuses) > i && statuses[i].External != nil && &statuses[i].External.Current.AverageValue != nil {
|
||||
current = statuses[i].External.Current.AverageValue.String()
|
||||
}
|
||||
list = append(list, fmt.Sprintf("%s/%s (avg)", current, spec.External.TargetAverageValue.String()))
|
||||
list = append(list, fmt.Sprintf("%s/%s (avg)", current, spec.External.Target.AverageValue.String()))
|
||||
} else {
|
||||
current := "<unknown>"
|
||||
if len(statuses) > i && statuses[i].External != nil {
|
||||
current = statuses[i].External.CurrentValue.String()
|
||||
current = statuses[i].External.Current.Value.String()
|
||||
}
|
||||
list = append(list, fmt.Sprintf("%s/%s", current, spec.External.TargetValue.String()))
|
||||
list = append(list, fmt.Sprintf("%s/%s", current, spec.External.Target.Value.String()))
|
||||
}
|
||||
case autoscaling.PodsMetricSourceType:
|
||||
current := "<unknown>"
|
||||
if len(statuses) > i && statuses[i].Pods != nil {
|
||||
current = statuses[i].Pods.CurrentAverageValue.String()
|
||||
current = statuses[i].Pods.Current.AverageValue.String()
|
||||
}
|
||||
list = append(list, fmt.Sprintf("%s/%s", current, spec.Pods.TargetAverageValue.String()))
|
||||
list = append(list, fmt.Sprintf("%s/%s", current, spec.Pods.Target.AverageValue.String()))
|
||||
case autoscaling.ObjectMetricSourceType:
|
||||
current := "<unknown>"
|
||||
if len(statuses) > i && statuses[i].Object != nil {
|
||||
current = statuses[i].Object.CurrentValue.String()
|
||||
current = statuses[i].Object.Current.Value.String()
|
||||
}
|
||||
list = append(list, fmt.Sprintf("%s/%s", current, spec.Object.TargetValue.String()))
|
||||
list = append(list, fmt.Sprintf("%s/%s", current, spec.Object.Target.Value.String()))
|
||||
case autoscaling.ResourceMetricSourceType:
|
||||
if spec.Resource.TargetAverageValue != nil {
|
||||
if spec.Resource.Target.AverageValue != nil {
|
||||
current := "<unknown>"
|
||||
if len(statuses) > i && statuses[i].Resource != nil {
|
||||
current = statuses[i].Resource.CurrentAverageValue.String()
|
||||
current = statuses[i].Resource.Current.AverageValue.String()
|
||||
}
|
||||
list = append(list, fmt.Sprintf("%s/%s", current, spec.Resource.TargetAverageValue.String()))
|
||||
list = append(list, fmt.Sprintf("%s/%s", current, spec.Resource.Target.AverageValue.String()))
|
||||
} else {
|
||||
current := "<unknown>"
|
||||
if len(statuses) > i && statuses[i].Resource != nil && statuses[i].Resource.CurrentAverageUtilization != nil {
|
||||
current = fmt.Sprintf("%d%%", *statuses[i].Resource.CurrentAverageUtilization)
|
||||
if len(statuses) > i && statuses[i].Resource != nil && statuses[i].Resource.Current.AverageUtilization != nil {
|
||||
current = fmt.Sprintf("%d%%", *statuses[i].Resource.Current.AverageUtilization)
|
||||
}
|
||||
|
||||
target := "<auto>"
|
||||
if spec.Resource.TargetAverageUtilization != nil {
|
||||
target = fmt.Sprintf("%d%%", *spec.Resource.TargetAverageUtilization)
|
||||
if spec.Resource.Target.AverageUtilization != nil {
|
||||
target = fmt.Sprintf("%d%%", *spec.Resource.Target.AverageUtilization)
|
||||
}
|
||||
list = append(list, fmt.Sprintf("%s/%s", current, target))
|
||||
}
|
||||
@ -1591,7 +1688,7 @@ func printHorizontalPodAutoscaler(obj *autoscaling.HorizontalPodAutoscaler, opti
|
||||
}
|
||||
maxPods := obj.Spec.MaxReplicas
|
||||
currentReplicas := obj.Status.CurrentReplicas
|
||||
row.Cells = append(row.Cells, obj.Name, reference, metrics, minPods, int64(maxPods), int64(currentReplicas), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, reference, metrics, minPods, int64(maxPods), int64(currentReplicas), translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -1611,7 +1708,7 @@ func printConfigMap(obj *api.ConfigMap, options printers.PrintOptions) ([]metav1
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
row.Cells = append(row.Cells, obj.Name, int64(len(obj.Data)), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, int64(len(obj.Data)), translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -1664,7 +1761,7 @@ func printNetworkPolicy(obj *networking.NetworkPolicy, options printers.PrintOpt
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
row.Cells = append(row.Cells, obj.Name, metav1.FormatLabelSelector(&obj.Spec.PodSelector), translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, obj.Name, metav1.FormatLabelSelector(&obj.Spec.PodSelector), translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
@ -1690,7 +1787,7 @@ func printStorageClass(obj *storage.StorageClass, options printers.PrintOptions)
|
||||
name += " (default)"
|
||||
}
|
||||
provtype := obj.Provisioner
|
||||
row.Cells = append(row.Cells, name, provtype, translateTimestamp(obj.CreationTimestamp))
|
||||
row.Cells = append(row.Cells, name, provtype, translateTimestampSince(obj.CreationTimestamp))
|
||||
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
@ -1707,6 +1804,31 @@ func printStorageClassList(list *storage.StorageClassList, options printers.Prin
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func printLease(obj *coordination.Lease, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
|
||||
var holderIdentity string
|
||||
if obj.Spec.HolderIdentity != nil {
|
||||
holderIdentity = *obj.Spec.HolderIdentity
|
||||
}
|
||||
row.Cells = append(row.Cells, obj.Name, holderIdentity, translateTimestampSince(obj.CreationTimestamp))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
func printLeaseList(list *coordination.LeaseList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
rows := make([]metav1beta1.TableRow, 0, len(list.Items))
|
||||
for i := range list.Items {
|
||||
r, err := printLease(&list.Items[i], options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows = append(rows, r...)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func printStatus(obj *metav1.Status, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
@ -1716,24 +1838,6 @@ func printStatus(obj *metav1.Status, options printers.PrintOptions) ([]metav1bet
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
// Lay out all the containers on one line if use wide output.
|
||||
// DEPRECATED: convert to TableHandler and use layoutContainerCells
|
||||
func layoutContainers(containers []api.Container, w io.Writer) error {
|
||||
var namesBuffer bytes.Buffer
|
||||
var imagesBuffer bytes.Buffer
|
||||
|
||||
for i, container := range containers {
|
||||
namesBuffer.WriteString(container.Name)
|
||||
imagesBuffer.WriteString(container.Image)
|
||||
if i != len(containers)-1 {
|
||||
namesBuffer.WriteString(",")
|
||||
imagesBuffer.WriteString(",")
|
||||
}
|
||||
}
|
||||
_, err := fmt.Fprintf(w, "\t%s\t%s", namesBuffer.String(), imagesBuffer.String())
|
||||
return err
|
||||
}
|
||||
|
||||
// Lay out all the containers on one line if use wide output.
|
||||
func layoutContainerCells(containers []api.Container) (names string, images string) {
|
||||
var namesBuffer bytes.Buffer
|
||||
@ -1776,7 +1880,7 @@ func printControllerRevision(obj *apps.ControllerRevision, options printers.Prin
|
||||
controllerName = printers.FormatResourceName(gvk.GroupKind(), controllerRef.Name, withKind)
|
||||
}
|
||||
revision := obj.Revision
|
||||
age := translateTimestamp(obj.CreationTimestamp)
|
||||
age := translateTimestampSince(obj.CreationTimestamp)
|
||||
row.Cells = append(row.Cells, obj.Name, controllerName, revision, age)
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
@ -1792,3 +1896,102 @@ func printControllerRevisionList(list *apps.ControllerRevisionList, options prin
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func printResourceQuota(resourceQuota *api.ResourceQuota, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: resourceQuota},
|
||||
}
|
||||
|
||||
resources := make([]api.ResourceName, 0, len(resourceQuota.Status.Hard))
|
||||
for resource := range resourceQuota.Status.Hard {
|
||||
resources = append(resources, resource)
|
||||
}
|
||||
sort.Sort(SortableResourceNames(resources))
|
||||
|
||||
requestColumn := bytes.NewBuffer([]byte{})
|
||||
limitColumn := bytes.NewBuffer([]byte{})
|
||||
for i := range resources {
|
||||
w := requestColumn
|
||||
resource := resources[i]
|
||||
usedQuantity := resourceQuota.Status.Used[resource]
|
||||
hardQuantity := resourceQuota.Status.Hard[resource]
|
||||
|
||||
// use limitColumn writer if a resource name prefixed with "limits" is found
|
||||
if pieces := strings.Split(resource.String(), "."); len(pieces) > 1 && pieces[0] == "limits" {
|
||||
w = limitColumn
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "%s: %s/%s, ", resource, usedQuantity.String(), hardQuantity.String())
|
||||
}
|
||||
|
||||
age := translateTimestampSince(resourceQuota.CreationTimestamp)
|
||||
row.Cells = append(row.Cells, resourceQuota.Name, age, strings.TrimSuffix(requestColumn.String(), ", "), strings.TrimSuffix(limitColumn.String(), ", "))
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
func printResourceQuotaList(list *api.ResourceQuotaList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
rows := make([]metav1beta1.TableRow, 0, len(list.Items))
|
||||
for i := range list.Items {
|
||||
r, err := printResourceQuota(&list.Items[i], options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows = append(rows, r...)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func printPriorityClass(obj *scheduling.PriorityClass, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: obj},
|
||||
}
|
||||
|
||||
name := obj.Name
|
||||
value := obj.Value
|
||||
globalDefault := obj.GlobalDefault
|
||||
row.Cells = append(row.Cells, name, int64(value), globalDefault, translateTimestampSince(obj.CreationTimestamp))
|
||||
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
func printPriorityClassList(list *scheduling.PriorityClassList, options printers.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
rows := make([]metav1beta1.TableRow, 0, len(list.Items))
|
||||
for i := range list.Items {
|
||||
r, err := printPriorityClass(&list.Items[i], options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows = append(rows, r...)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
func printBoolPtr(value *bool) string {
|
||||
if value != nil {
|
||||
return printBool(*value)
|
||||
}
|
||||
|
||||
return "<unset>"
|
||||
}
|
||||
|
||||
func printBool(value bool) string {
|
||||
if value {
|
||||
return "True"
|
||||
}
|
||||
|
||||
return "False"
|
||||
}
|
||||
|
||||
type SortableResourceNames []api.ResourceName
|
||||
|
||||
func (list SortableResourceNames) Len() int {
|
||||
return len(list)
|
||||
}
|
||||
|
||||
func (list SortableResourceNames) Swap(i, j int) {
|
||||
list[i], list[j] = list[j], list[i]
|
||||
}
|
||||
|
||||
func (list SortableResourceNames) Less(i, j int) bool {
|
||||
return list[i] < list[j]
|
||||
}
|
||||
|
491
vendor/k8s.io/kubernetes/pkg/printers/internalversion/printers_test.go
generated
vendored
491
vendor/k8s.io/kubernetes/pkg/printers/internalversion/printers_test.go
generated
vendored
@ -28,7 +28,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ghodss/yaml"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
@ -41,25 +41,22 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
genericprinters "k8s.io/cli-runtime/pkg/genericclioptions/printers"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
"k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||
"k8s.io/kubernetes/pkg/apis/batch"
|
||||
"k8s.io/kubernetes/pkg/apis/coordination"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/policy"
|
||||
"k8s.io/kubernetes/pkg/apis/scheduling"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
genericprinters "k8s.io/kubernetes/pkg/kubectl/genericclioptions/printers"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
)
|
||||
|
||||
func init() {
|
||||
legacyscheme.Scheme.AddKnownTypes(schema.GroupVersion{Group: "", Version: runtime.APIVersionInternal}, &TestPrintType{})
|
||||
legacyscheme.Scheme.AddKnownTypes(schema.GroupVersion{Group: "", Version: "v1"}, &TestPrintType{})
|
||||
}
|
||||
|
||||
var testData = TestStruct{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: "foo/bar", Kind: "TestStruct"},
|
||||
Key: "testValue",
|
||||
@ -256,8 +253,12 @@ func testPrinter(t *testing.T, printer printers.ResourcePrinter, unmarshalFunc f
|
||||
}
|
||||
}
|
||||
|
||||
func yamlUnmarshal(data []byte, v interface{}) error {
|
||||
return yaml.Unmarshal(data, v)
|
||||
}
|
||||
|
||||
func TestYAMLPrinter(t *testing.T) {
|
||||
testPrinter(t, genericprinters.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&genericprinters.YAMLPrinter{}), yaml.Unmarshal)
|
||||
testPrinter(t, genericprinters.NewTypeSetter(legacyscheme.Scheme).ToPrinter(&genericprinters.YAMLPrinter{}), yamlUnmarshal)
|
||||
}
|
||||
|
||||
func TestJSONPrinter(t *testing.T) {
|
||||
@ -1151,6 +1152,10 @@ func TestPrintHumanReadableService(t *testing.T) {
|
||||
Port: 8000,
|
||||
Protocol: "TCP",
|
||||
},
|
||||
{
|
||||
Port: 7777,
|
||||
Protocol: "SCTP",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -1288,7 +1293,7 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Image: "foo/bar",
|
||||
Image: "foo/bar",
|
||||
TerminationMessagePath: api.TerminationMessagePathDefault,
|
||||
ImagePullPolicy: api.PullIfNotPresent,
|
||||
},
|
||||
@ -1644,6 +1649,9 @@ func TestPrintPod(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrintPodwide(t *testing.T) {
|
||||
condition1 := "condition1"
|
||||
condition2 := "condition2"
|
||||
condition3 := "condition3"
|
||||
tests := []struct {
|
||||
pod api.Pod
|
||||
expect []metav1beta1.TableRow
|
||||
@ -1655,8 +1663,29 @@ func TestPrintPodwide(t *testing.T) {
|
||||
Spec: api.PodSpec{
|
||||
Containers: make([]api.Container, 2),
|
||||
NodeName: "test1",
|
||||
ReadinessGates: []api.PodReadinessGate{
|
||||
{
|
||||
ConditionType: api.PodConditionType(condition1),
|
||||
},
|
||||
{
|
||||
ConditionType: api.PodConditionType(condition2),
|
||||
},
|
||||
{
|
||||
ConditionType: api.PodConditionType(condition3),
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: api.PodStatus{
|
||||
Conditions: []api.PodCondition{
|
||||
{
|
||||
Type: api.PodConditionType(condition1),
|
||||
Status: api.ConditionFalse,
|
||||
},
|
||||
{
|
||||
Type: api.PodConditionType(condition2),
|
||||
Status: api.ConditionTrue,
|
||||
},
|
||||
},
|
||||
Phase: "podPhase",
|
||||
PodIP: "1.1.1.1",
|
||||
ContainerStatuses: []api.ContainerStatus{
|
||||
@ -1666,7 +1695,7 @@ func TestPrintPodwide(t *testing.T) {
|
||||
NominatedNodeName: "node1",
|
||||
},
|
||||
},
|
||||
[]metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", int64(6), "<unknown>", "1.1.1.1", "test1", "node1"}}},
|
||||
[]metav1beta1.TableRow{{Cells: []interface{}{"test1", "1/2", "podPhase", int64(6), "<unknown>", "1.1.1.1", "test1", "node1", "1/3"}}},
|
||||
},
|
||||
{
|
||||
// Test when the NodeName and PodIP are none
|
||||
@ -1685,7 +1714,7 @@ func TestPrintPodwide(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
[]metav1beta1.TableRow{{Cells: []interface{}{"test2", "1/2", "ContainerWaitingReason", int64(6), "<unknown>", "<none>", "<none>"}}},
|
||||
[]metav1beta1.TableRow{{Cells: []interface{}{"test2", "1/2", "ContainerWaitingReason", int64(6), "<unknown>", "<none>", "<none>", "<none>", "<none>"}}},
|
||||
},
|
||||
}
|
||||
|
||||
@ -1918,18 +1947,43 @@ type stringTestList []struct {
|
||||
name, got, exp string
|
||||
}
|
||||
|
||||
func TestTranslateTimestamp(t *testing.T) {
|
||||
func TestTranslateTimestampSince(t *testing.T) {
|
||||
tl := stringTestList{
|
||||
{"a while from now", translateTimestamp(metav1.Time{Time: time.Now().Add(2.1e9)}), "<invalid>"},
|
||||
{"almost now", translateTimestamp(metav1.Time{Time: time.Now().Add(1.9e9)}), "0s"},
|
||||
{"now", translateTimestamp(metav1.Time{Time: time.Now()}), "0s"},
|
||||
{"unknown", translateTimestamp(metav1.Time{}), "<unknown>"},
|
||||
{"30 seconds ago", translateTimestamp(metav1.Time{Time: time.Now().Add(-3e10)}), "30s"},
|
||||
{"5 minutes ago", translateTimestamp(metav1.Time{Time: time.Now().Add(-3e11)}), "5m"},
|
||||
{"an hour ago", translateTimestamp(metav1.Time{Time: time.Now().Add(-6e12)}), "1h"},
|
||||
{"2 days ago", translateTimestamp(metav1.Time{Time: time.Now().UTC().AddDate(0, 0, -2)}), "2d"},
|
||||
{"months ago", translateTimestamp(metav1.Time{Time: time.Now().UTC().AddDate(0, 0, -90)}), "90d"},
|
||||
{"10 years ago", translateTimestamp(metav1.Time{Time: time.Now().UTC().AddDate(-10, 0, 0)}), "10y"},
|
||||
{"a while from now", translateTimestampSince(metav1.Time{Time: time.Now().Add(2.1e9)}), "<invalid>"},
|
||||
{"almost now", translateTimestampSince(metav1.Time{Time: time.Now().Add(1.9e9)}), "0s"},
|
||||
{"now", translateTimestampSince(metav1.Time{Time: time.Now()}), "0s"},
|
||||
{"unknown", translateTimestampSince(metav1.Time{}), "<unknown>"},
|
||||
{"30 seconds ago", translateTimestampSince(metav1.Time{Time: time.Now().Add(-3e10)}), "30s"},
|
||||
{"5 minutes ago", translateTimestampSince(metav1.Time{Time: time.Now().Add(-3e11)}), "5m"},
|
||||
{"an hour ago", translateTimestampSince(metav1.Time{Time: time.Now().Add(-6e12)}), "100m"},
|
||||
{"2 days ago", translateTimestampSince(metav1.Time{Time: time.Now().UTC().AddDate(0, 0, -2)}), "2d"},
|
||||
{"months ago", translateTimestampSince(metav1.Time{Time: time.Now().UTC().AddDate(0, 0, -90)}), "90d"},
|
||||
{"10 years ago", translateTimestampSince(metav1.Time{Time: time.Now().UTC().AddDate(-10, 0, 0)}), "10y"},
|
||||
}
|
||||
for _, test := range tl {
|
||||
if test.got != test.exp {
|
||||
t.Errorf("On %v, expected '%v', but got '%v'",
|
||||
test.name, test.exp, test.got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTranslateTimestampUntil(t *testing.T) {
|
||||
// Since this method compares the time with time.Now() internally,
|
||||
// small buffers of 0.1 seconds are added on comparing times to consider method call overhead.
|
||||
// Otherwise, the output strings become shorter than expected.
|
||||
const buf = 1e8
|
||||
tl := stringTestList{
|
||||
{"a while ago", translateTimestampUntil(metav1.Time{Time: time.Now().Add(-2.1e9)}), "<invalid>"},
|
||||
{"almost now", translateTimestampUntil(metav1.Time{Time: time.Now().Add(-1.9e9)}), "0s"},
|
||||
{"now", translateTimestampUntil(metav1.Time{Time: time.Now()}), "0s"},
|
||||
{"unknown", translateTimestampUntil(metav1.Time{}), "<unknown>"},
|
||||
{"in 30 seconds", translateTimestampUntil(metav1.Time{Time: time.Now().Add(3e10 + buf)}), "30s"},
|
||||
{"in 5 minutes", translateTimestampUntil(metav1.Time{Time: time.Now().Add(3e11 + buf)}), "5m"},
|
||||
{"in an hour", translateTimestampUntil(metav1.Time{Time: time.Now().Add(6e12 + buf)}), "100m"},
|
||||
{"in 2 days", translateTimestampUntil(metav1.Time{Time: time.Now().UTC().AddDate(0, 0, 2).Add(buf)}), "2d"},
|
||||
{"in months", translateTimestampUntil(metav1.Time{Time: time.Now().UTC().AddDate(0, 0, 90).Add(buf)}), "90d"},
|
||||
{"in 10 years", translateTimestampUntil(metav1.Time{Time: time.Now().UTC().AddDate(10, 0, 0).Add(buf)}), "10y"},
|
||||
}
|
||||
for _, test := range tl {
|
||||
if test.got != test.exp {
|
||||
@ -1941,17 +1995,17 @@ func TestTranslateTimestamp(t *testing.T) {
|
||||
|
||||
func TestPrintDeployment(t *testing.T) {
|
||||
tests := []struct {
|
||||
deployment extensions.Deployment
|
||||
deployment apps.Deployment
|
||||
expect string
|
||||
wideExpect string
|
||||
}{
|
||||
{
|
||||
extensions.Deployment{
|
||||
apps.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test1",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
|
||||
},
|
||||
Spec: extensions.DeploymentSpec{
|
||||
Spec: apps.DeploymentSpec{
|
||||
Replicas: 5,
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
@ -1969,15 +2023,15 @@ func TestPrintDeployment(t *testing.T) {
|
||||
},
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
|
||||
},
|
||||
Status: extensions.DeploymentStatus{
|
||||
Status: apps.DeploymentStatus{
|
||||
Replicas: 10,
|
||||
UpdatedReplicas: 2,
|
||||
AvailableReplicas: 1,
|
||||
UnavailableReplicas: 4,
|
||||
},
|
||||
},
|
||||
"test1\t5\t10\t2\t1\t0s\n",
|
||||
"test1\t5\t10\t2\t1\t0s\tfake-container1,fake-container2\tfake-image1,fake-image2\tfoo=bar\n",
|
||||
"test1\t0/5\t2\t1\t0s\n",
|
||||
"test1\t0/5\t2\t1\t0s\tfake-container1,fake-container2\tfake-image1,fake-image2\tfoo=bar\n",
|
||||
},
|
||||
}
|
||||
|
||||
@ -2010,21 +2064,21 @@ func TestPrintDeployment(t *testing.T) {
|
||||
|
||||
func TestPrintDaemonSet(t *testing.T) {
|
||||
tests := []struct {
|
||||
ds extensions.DaemonSet
|
||||
ds apps.DaemonSet
|
||||
startsWith string
|
||||
}{
|
||||
{
|
||||
extensions.DaemonSet{
|
||||
apps.DaemonSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test1",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
|
||||
},
|
||||
Spec: extensions.DaemonSetSpec{
|
||||
Spec: apps.DaemonSetSpec{
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{Containers: make([]api.Container, 2)},
|
||||
},
|
||||
},
|
||||
Status: extensions.DaemonSetStatus{
|
||||
Status: apps.DaemonSetStatus{
|
||||
CurrentNumberScheduled: 2,
|
||||
DesiredNumberScheduled: 3,
|
||||
NumberReady: 1,
|
||||
@ -2054,6 +2108,7 @@ func TestPrintDaemonSet(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPrintJob(t *testing.T) {
|
||||
now := time.Now()
|
||||
completions := int32(2)
|
||||
tests := []struct {
|
||||
job batch.Job
|
||||
@ -2072,7 +2127,7 @@ func TestPrintJob(t *testing.T) {
|
||||
Succeeded: 1,
|
||||
},
|
||||
},
|
||||
"job1\t2\t1\t0s\n",
|
||||
"job1\t1/2\t\t0s\n",
|
||||
},
|
||||
{
|
||||
batch.Job{
|
||||
@ -2087,7 +2142,40 @@ func TestPrintJob(t *testing.T) {
|
||||
Succeeded: 0,
|
||||
},
|
||||
},
|
||||
"job2\t<none>\t0\t10y\n",
|
||||
"job2\t0/1\t\t10y\n",
|
||||
},
|
||||
{
|
||||
batch.Job{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "job3",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().AddDate(-10, 0, 0)},
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
Completions: nil,
|
||||
},
|
||||
Status: batch.JobStatus{
|
||||
Succeeded: 0,
|
||||
StartTime: &metav1.Time{Time: now.Add(time.Minute)},
|
||||
CompletionTime: &metav1.Time{Time: now.Add(31 * time.Minute)},
|
||||
},
|
||||
},
|
||||
"job3\t0/1\t30m\t10y\n",
|
||||
},
|
||||
{
|
||||
batch.Job{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "job4",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().AddDate(-10, 0, 0)},
|
||||
},
|
||||
Spec: batch.JobSpec{
|
||||
Completions: nil,
|
||||
},
|
||||
Status: batch.JobStatus{
|
||||
Succeeded: 0,
|
||||
StartTime: &metav1.Time{Time: time.Now().Add(-20 * time.Minute)},
|
||||
},
|
||||
},
|
||||
"job4\t0/1\t20m\t10y\n",
|
||||
},
|
||||
}
|
||||
|
||||
@ -2112,6 +2200,10 @@ func TestPrintHPA(t *testing.T) {
|
||||
minReplicasVal := int32(2)
|
||||
targetUtilizationVal := int32(80)
|
||||
currentUtilizationVal := int32(50)
|
||||
metricLabelSelector, err := metav1.ParseToLabelSelector("label=value")
|
||||
if err != nil {
|
||||
t.Errorf("unable to parse label selector: %v", err)
|
||||
}
|
||||
tests := []struct {
|
||||
hpa autoscaling.HorizontalPodAutoscaler
|
||||
expected string
|
||||
@ -2149,13 +2241,14 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ExternalMetricSourceType,
|
||||
External: &autoscaling.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"label": "value",
|
||||
},
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-external-metric",
|
||||
Selector: metricLabelSelector,
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.AverageValueMetricType,
|
||||
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
MetricName: "some-external-metric",
|
||||
TargetAverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2182,13 +2275,14 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ExternalMetricSourceType,
|
||||
External: &autoscaling.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"label": "value",
|
||||
},
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-external-metric",
|
||||
Selector: metricLabelSelector,
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.AverageValueMetricType,
|
||||
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
MetricName: "some-external-metric",
|
||||
TargetAverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2200,13 +2294,13 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ExternalMetricSourceType,
|
||||
External: &autoscaling.ExternalMetricStatus{
|
||||
MetricSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"label": "value",
|
||||
},
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-external-metric",
|
||||
Selector: metricLabelSelector,
|
||||
},
|
||||
Current: autoscaling.MetricValueStatus{
|
||||
AverageValue: resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
},
|
||||
MetricName: "some-external-metric",
|
||||
CurrentAverageValue: resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2229,13 +2323,14 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ExternalMetricSourceType,
|
||||
External: &autoscaling.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"label": "value",
|
||||
},
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-service-metric",
|
||||
Selector: metricLabelSelector,
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.ValueMetricType,
|
||||
Value: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
MetricName: "some-service-metric",
|
||||
TargetValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2262,13 +2357,14 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ExternalMetricSourceType,
|
||||
External: &autoscaling.ExternalMetricSource{
|
||||
MetricSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"label": "value",
|
||||
},
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-external-metric",
|
||||
Selector: metricLabelSelector,
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.ValueMetricType,
|
||||
Value: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
MetricName: "some-external-metric",
|
||||
TargetValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2280,8 +2376,12 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ExternalMetricSourceType,
|
||||
External: &autoscaling.ExternalMetricStatus{
|
||||
MetricName: "some-external-metric",
|
||||
CurrentValue: *resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-external-metric",
|
||||
},
|
||||
Current: autoscaling.MetricValueStatus{
|
||||
Value: resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2304,8 +2404,13 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.PodsMetricSourceType,
|
||||
Pods: &autoscaling.PodsMetricSource{
|
||||
MetricName: "some-pods-metric",
|
||||
TargetAverageValue: *resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-pods-metric",
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.AverageValueMetricType,
|
||||
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2332,8 +2437,13 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.PodsMetricSourceType,
|
||||
Pods: &autoscaling.PodsMetricSource{
|
||||
MetricName: "some-pods-metric",
|
||||
TargetAverageValue: *resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-pods-metric",
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.AverageValueMetricType,
|
||||
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2345,8 +2455,12 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.PodsMetricSourceType,
|
||||
Pods: &autoscaling.PodsMetricStatus{
|
||||
MetricName: "some-pods-metric",
|
||||
CurrentAverageValue: *resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-pods-metric",
|
||||
},
|
||||
Current: autoscaling.MetricValueStatus{
|
||||
AverageValue: resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2369,12 +2483,17 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ObjectMetricSourceType,
|
||||
Object: &autoscaling.ObjectMetricSource{
|
||||
Target: autoscaling.CrossVersionObjectReference{
|
||||
DescribedObject: autoscaling.CrossVersionObjectReference{
|
||||
Name: "some-service",
|
||||
Kind: "Service",
|
||||
},
|
||||
MetricName: "some-service-metric",
|
||||
TargetValue: *resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-service-metric",
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.ValueMetricType,
|
||||
Value: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2401,12 +2520,17 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ObjectMetricSourceType,
|
||||
Object: &autoscaling.ObjectMetricSource{
|
||||
Target: autoscaling.CrossVersionObjectReference{
|
||||
DescribedObject: autoscaling.CrossVersionObjectReference{
|
||||
Name: "some-service",
|
||||
Kind: "Service",
|
||||
},
|
||||
MetricName: "some-service-metric",
|
||||
TargetValue: *resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-service-metric",
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.ValueMetricType,
|
||||
Value: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2418,12 +2542,16 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ObjectMetricSourceType,
|
||||
Object: &autoscaling.ObjectMetricStatus{
|
||||
Target: autoscaling.CrossVersionObjectReference{
|
||||
DescribedObject: autoscaling.CrossVersionObjectReference{
|
||||
Name: "some-service",
|
||||
Kind: "Service",
|
||||
},
|
||||
MetricName: "some-service-metric",
|
||||
CurrentValue: *resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-service-metric",
|
||||
},
|
||||
Current: autoscaling.MetricValueStatus{
|
||||
Value: resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2446,8 +2574,11 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ResourceMetricSourceType,
|
||||
Resource: &autoscaling.ResourceMetricSource{
|
||||
Name: api.ResourceCPU,
|
||||
TargetAverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
Name: api.ResourceCPU,
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.AverageValueMetricType,
|
||||
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2474,8 +2605,11 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ResourceMetricSourceType,
|
||||
Resource: &autoscaling.ResourceMetricSource{
|
||||
Name: api.ResourceCPU,
|
||||
TargetAverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
Name: api.ResourceCPU,
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.AverageValueMetricType,
|
||||
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2487,8 +2621,10 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.ResourceMetricSourceType,
|
||||
Resource: &autoscaling.ResourceMetricStatus{
|
||||
Name: api.ResourceCPU,
|
||||
CurrentAverageValue: *resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
Name: api.ResourceCPU,
|
||||
Current: autoscaling.MetricValueStatus{
|
||||
AverageValue: resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2512,7 +2648,10 @@ func TestPrintHPA(t *testing.T) {
|
||||
Type: autoscaling.ResourceMetricSourceType,
|
||||
Resource: &autoscaling.ResourceMetricSource{
|
||||
Name: api.ResourceCPU,
|
||||
TargetAverageUtilization: &targetUtilizationVal,
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.UtilizationMetricType,
|
||||
AverageUtilization: &targetUtilizationVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2540,7 +2679,10 @@ func TestPrintHPA(t *testing.T) {
|
||||
Type: autoscaling.ResourceMetricSourceType,
|
||||
Resource: &autoscaling.ResourceMetricSource{
|
||||
Name: api.ResourceCPU,
|
||||
TargetAverageUtilization: &targetUtilizationVal,
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.UtilizationMetricType,
|
||||
AverageUtilization: &targetUtilizationVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2553,8 +2695,10 @@ func TestPrintHPA(t *testing.T) {
|
||||
Type: autoscaling.ResourceMetricSourceType,
|
||||
Resource: &autoscaling.ResourceMetricStatus{
|
||||
Name: api.ResourceCPU,
|
||||
CurrentAverageUtilization: ¤tUtilizationVal,
|
||||
CurrentAverageValue: *resource.NewMilliQuantity(40, resource.DecimalSI),
|
||||
Current: autoscaling.MetricValueStatus{
|
||||
AverageUtilization: ¤tUtilizationVal,
|
||||
AverageValue: resource.NewMilliQuantity(40, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2577,22 +2721,35 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.PodsMetricSourceType,
|
||||
Pods: &autoscaling.PodsMetricSource{
|
||||
MetricName: "some-pods-metric",
|
||||
TargetAverageValue: *resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-pods-metric",
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.AverageValueMetricType,
|
||||
AverageValue: resource.NewMilliQuantity(100, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: autoscaling.ResourceMetricSourceType,
|
||||
Resource: &autoscaling.ResourceMetricSource{
|
||||
Name: api.ResourceCPU,
|
||||
TargetAverageUtilization: &targetUtilizationVal,
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.UtilizationMetricType,
|
||||
AverageUtilization: &targetUtilizationVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: autoscaling.PodsMetricSourceType,
|
||||
Pods: &autoscaling.PodsMetricSource{
|
||||
MetricName: "other-pods-metric",
|
||||
TargetAverageValue: *resource.NewMilliQuantity(400, resource.DecimalSI),
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "other-pods-metric",
|
||||
},
|
||||
Target: autoscaling.MetricTarget{
|
||||
Type: autoscaling.AverageValueMetricType,
|
||||
AverageValue: resource.NewMilliQuantity(400, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -2604,16 +2761,22 @@ func TestPrintHPA(t *testing.T) {
|
||||
{
|
||||
Type: autoscaling.PodsMetricSourceType,
|
||||
Pods: &autoscaling.PodsMetricStatus{
|
||||
MetricName: "some-pods-metric",
|
||||
CurrentAverageValue: *resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
Metric: autoscaling.MetricIdentifier{
|
||||
Name: "some-pods-metric",
|
||||
},
|
||||
Current: autoscaling.MetricValueStatus{
|
||||
AverageValue: resource.NewMilliQuantity(50, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: autoscaling.ResourceMetricSourceType,
|
||||
Resource: &autoscaling.ResourceMetricStatus{
|
||||
Name: api.ResourceCPU,
|
||||
CurrentAverageUtilization: ¤tUtilizationVal,
|
||||
CurrentAverageValue: *resource.NewMilliQuantity(40, resource.DecimalSI),
|
||||
Current: autoscaling.MetricValueStatus{
|
||||
AverageUtilization: ¤tUtilizationVal,
|
||||
AverageValue: resource.NewMilliQuantity(40, resource.DecimalSI),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -3015,17 +3178,17 @@ func boolP(b bool) *bool {
|
||||
|
||||
func TestPrintReplicaSet(t *testing.T) {
|
||||
tests := []struct {
|
||||
replicaSet extensions.ReplicaSet
|
||||
replicaSet apps.ReplicaSet
|
||||
expect string
|
||||
wideExpect string
|
||||
}{
|
||||
{
|
||||
extensions.ReplicaSet{
|
||||
apps.ReplicaSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test1",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
|
||||
},
|
||||
Spec: extensions.ReplicaSetSpec{
|
||||
Spec: apps.ReplicaSetSpec{
|
||||
Replicas: 5,
|
||||
Template: api.PodTemplateSpec{
|
||||
Spec: api.PodSpec{
|
||||
@ -3043,7 +3206,7 @@ func TestPrintReplicaSet(t *testing.T) {
|
||||
},
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"foo": "bar"}},
|
||||
},
|
||||
Status: extensions.ReplicaSetStatus{
|
||||
Status: apps.ReplicaSetStatus{
|
||||
Replicas: 5,
|
||||
ReadyReplicas: 2,
|
||||
},
|
||||
@ -3299,6 +3462,100 @@ func TestPrintStorageClass(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintLease(t *testing.T) {
|
||||
holder1 := "holder1"
|
||||
holder2 := "holder2"
|
||||
tests := []struct {
|
||||
sc coordination.Lease
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
coordination.Lease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "lease1",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
|
||||
},
|
||||
Spec: coordination.LeaseSpec{
|
||||
HolderIdentity: &holder1,
|
||||
},
|
||||
},
|
||||
"lease1\tholder1\t0s\n",
|
||||
},
|
||||
{
|
||||
coordination.Lease{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "lease2",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().Add(-3e11)},
|
||||
},
|
||||
Spec: coordination.LeaseSpec{
|
||||
HolderIdentity: &holder2,
|
||||
},
|
||||
},
|
||||
"lease2\tholder2\t5m\n",
|
||||
},
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
for _, test := range tests {
|
||||
table, err := printers.NewTablePrinter().With(AddHandlers).PrintTable(&test.sc, printers.PrintOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := printers.PrintTable(table, buf, printers.PrintOptions{NoHeaders: true}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if buf.String() != test.expect {
|
||||
t.Fatalf("Expected: %s, got: %s", test.expect, buf.String())
|
||||
}
|
||||
buf.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintPriorityClass(t *testing.T) {
|
||||
tests := []struct {
|
||||
pc scheduling.PriorityClass
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
scheduling.PriorityClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pc1",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().Add(1.9e9)},
|
||||
},
|
||||
Value: 1,
|
||||
},
|
||||
"pc1\t1\tfalse\t0s\n",
|
||||
},
|
||||
{
|
||||
scheduling.PriorityClass{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pc2",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().Add(-3e11)},
|
||||
},
|
||||
Value: 1000000000,
|
||||
GlobalDefault: true,
|
||||
},
|
||||
"pc2\t1000000000\ttrue\t5m\n",
|
||||
},
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
for _, test := range tests {
|
||||
table, err := printers.NewTablePrinter().With(AddHandlers).PrintTable(&test.pc, printers.PrintOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
verifyTable(t, table)
|
||||
if err := printers.PrintTable(table, buf, printers.PrintOptions{NoHeaders: true}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if buf.String() != test.expect {
|
||||
t.Fatalf("Expected: %s, got: %s", test.expect, buf.String())
|
||||
}
|
||||
buf.Reset()
|
||||
}
|
||||
}
|
||||
|
||||
func verifyTable(t *testing.T, table *metav1beta1.Table) {
|
||||
var panicErr interface{}
|
||||
func() {
|
||||
@ -3312,3 +3569,27 @@ func verifyTable(t *testing.T, table *metav1beta1.Table) {
|
||||
t.Errorf("unexpected panic during deepcopy of table %#v: %v", table, panicErr)
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyDatesInOrder checks the start of each line for a RFC1123Z date
|
||||
// and posts error if all subsequent dates are not equal or increasing
|
||||
func VerifyDatesInOrder(
|
||||
resultToTest, rowDelimiter, columnDelimiter string, t *testing.T) {
|
||||
lines := strings.Split(resultToTest, rowDelimiter)
|
||||
var previousTime time.Time
|
||||
for _, str := range lines {
|
||||
columns := strings.Split(str, columnDelimiter)
|
||||
if len(columns) > 0 {
|
||||
currentTime, err := time.Parse(time.RFC1123Z, columns[0])
|
||||
if err == nil {
|
||||
if previousTime.After(currentTime) {
|
||||
t.Errorf(
|
||||
"Output is not sorted by time. %s should be listed after %s. Complete output: %s",
|
||||
previousTime.Format(time.RFC1123Z),
|
||||
currentTime.Format(time.RFC1123Z),
|
||||
resultToTest)
|
||||
}
|
||||
previousTime = currentTime
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
4
vendor/k8s.io/kubernetes/pkg/printers/storage/BUILD
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/printers/storage/BUILD
generated
vendored
@ -11,8 +11,8 @@ go_library(
|
||||
importpath = "k8s.io/kubernetes/pkg/printers/storage",
|
||||
deps = [
|
||||
"//pkg/printers:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
2
vendor/k8s.io/kubernetes/pkg/printers/tabwriter.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/printers/tabwriter.go
generated
vendored
@ -22,7 +22,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
tabwriterMinWidth = 10
|
||||
tabwriterMinWidth = 6
|
||||
tabwriterWidth = 4
|
||||
tabwriterPadding = 3
|
||||
tabwriterPadChar = ' '
|
||||
|
Reference in New Issue
Block a user