Bumping k8s dependencies to 1.13

This commit is contained in:
Cheng Xing
2018-11-16 14:08:25 -08:00
parent 305407125c
commit b4c0b68ec7
8002 changed files with 884099 additions and 276228 deletions

View File

@@ -30,26 +30,27 @@ go_library(
"//pkg/kubectl/cmd/templates:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/genericclioptions:go_default_library",
"//pkg/kubectl/genericclioptions/resource:go_default_library",
"//pkg/kubectl/scheme:go_default_library",
"//pkg/kubectl/util/i18n:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/printers/internalversion:go_default_library",
"//pkg/util/interrupt:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors: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/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//staging/src/k8s.io/client-go/tools/watch:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/spf13/cobra: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/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/util/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
],
)
@@ -66,28 +67,32 @@ go_test(
],
embed = [":go_default_library"],
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/api/testing:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/apis/core/v1:go_default_library",
"//pkg/kubectl/cmd/testing:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/cmd/util/openapi:go_default_library",
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
"//pkg/kubectl/genericclioptions:go_default_library",
"//pkg/kubectl/genericclioptions/resource:go_default_library",
"//pkg/kubectl/scheme: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/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/streaming:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
"//vendor/k8s.io/client-go/rest/watch:go_default_library",
"//staging/src/k8s.io/api/apps/v1:go_default_library",
"//staging/src/k8s.io/api/autoscaling/v1: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/core/v1:go_default_library",
"//staging/src/k8s.io/api/extensions/v1beta1: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",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/serializer/streaming:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions:go_default_library",
"//staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource:go_default_library",
"//staging/src/k8s.io/client-go/rest:go_default_library",
"//staging/src/k8s.io/client-go/rest/fake:go_default_library",
"//staging/src/k8s.io/client-go/rest/watch:go_default_library",
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
],
)

View File

@@ -17,6 +17,7 @@ limitations under the License.
package get
import (
"context"
"encoding/json"
"fmt"
"io"
@@ -35,14 +36,15 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
"k8s.io/client-go/rest"
watchtools "k8s.io/client-go/tools/watch"
"k8s.io/kubernetes/pkg/api/legacyscheme"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
"k8s.io/kubernetes/pkg/printers"
"k8s.io/kubernetes/pkg/util/interrupt"
@@ -51,7 +53,7 @@ import (
// GetOptions contains the input to the get command.
type GetOptions struct {
PrintFlags *PrintFlags
ToPrinter func(*meta.RESTMapping, bool) (printers.ResourcePrinterFunc, error)
ToPrinter func(*meta.RESTMapping, bool, bool) (printers.ResourcePrinterFunc, error)
IsHumanReadablePrinter bool
PrintWithOpenAPICols bool
@@ -205,10 +207,10 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
o.NoHeaders = cmdutil.GetFlagBool(cmd, "no-headers")
// TODO (soltysh): currently we don't support sorting and custom columns
// TODO (soltysh): currently we don't support custom columns
// with server side print. So in these cases force the old behavior.
outputOption := cmd.Flags().Lookup("output").Value.String()
if o.Sort && outputOption == "custom-columns" {
if outputOption == "custom-columns" {
o.ServerPrint = false
}
@@ -224,10 +226,7 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
o.IncludeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, false)
if resource.MultipleTypesRequested(args) {
o.PrintFlags.EnsureWithKind()
}
o.ToPrinter = func(mapping *meta.RESTMapping, withNamespace bool) (printers.ResourcePrinterFunc, error) {
o.ToPrinter = func(mapping *meta.RESTMapping, withNamespace bool, withKind bool) (printers.ResourcePrinterFunc, error) {
// make a new copy of current flags / opts before mutating
printFlags := o.PrintFlags.Copy()
@@ -242,6 +241,9 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri
if withNamespace {
printFlags.EnsureWithNamespace()
}
if withKind {
printFlags.EnsureWithKind()
}
printer, err := printFlags.ToPrinter()
if err != nil {
@@ -294,6 +296,96 @@ func (o *GetOptions) Validate(cmd *cobra.Command) error {
return nil
}
type OriginalPositioner interface {
OriginalPosition(int) int
}
type NopPositioner struct{}
func (t *NopPositioner) OriginalPosition(ix int) int {
return ix
}
type RuntimeSorter struct {
field string
decoder runtime.Decoder
objects []runtime.Object
positioner OriginalPositioner
}
func (r *RuntimeSorter) Sort() error {
if len(r.objects) <= 1 {
// a list is only considered "sorted" if there are 0 or 1 items in it
// AND (if 1 item) the item is not a Table object
_, isTable := r.objects[0].(*metav1beta1.Table)
if len(r.objects) == 0 || !isTable {
return nil
}
}
includesTable := false
includesRuntimeObjs := false
for _, obj := range r.objects {
switch t := obj.(type) {
case *metav1beta1.Table:
includesTable = true
if err := kubectl.NewTableSorter(t, r.field).Sort(); err != nil {
continue
}
default:
includesRuntimeObjs = true
}
}
// we use a NopPositioner when dealing with Table objects
// because the objects themselves are not swapped, but rather
// the rows in each object are swapped / sorted.
r.positioner = &NopPositioner{}
if includesRuntimeObjs && includesTable {
return fmt.Errorf("sorting is not supported on mixed Table and non-Table object lists")
}
if includesTable {
return nil
}
// if not dealing with a Table response from the server, assume
// all objects are runtime.Object as usual, and sort using old method.
var err error
if r.positioner, err = kubectl.SortObjects(r.decoder, r.objects, r.field); err != nil {
return err
}
return nil
}
func (r *RuntimeSorter) OriginalPosition(ix int) int {
if r.positioner == nil {
return 0
}
return r.positioner.OriginalPosition(ix)
}
// allows custom decoder to be set for testing
func (r *RuntimeSorter) WithDecoder(decoder runtime.Decoder) *RuntimeSorter {
r.decoder = decoder
return r
}
func NewRuntimeSorter(objects []runtime.Object, sortBy string) *RuntimeSorter {
parsedField, err := printers.RelaxedJSONPathExpression(sortBy)
if err != nil {
parsedField = sortBy
}
return &RuntimeSorter{
field: parsedField,
decoder: cmdutil.InternalVersionDecoder(),
objects: objects,
}
}
// Run performs the get operation.
// TODO: remove the need to pass these arguments, like other commands.
func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
@@ -304,6 +396,18 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
return o.watch(f, cmd, args)
}
// openapi printing is mutually exclusive with server side printing
if o.PrintWithOpenAPICols && o.ServerPrint {
fmt.Fprintf(o.IOStreams.ErrOut, "warning: --%s requested, --%s will be ignored\n", useOpenAPIPrintColumnFlagLabel, useServerPrintColumns)
}
chunkSize := o.ChunkSize
if o.Sort {
// TODO(juanvallejo): in the future, we could have the client use chunking
// to gather all results, then sort them all at the end to reduce server load.
chunkSize = 0
}
r := f.NewBuilder().
Unstructured().
NamespaceParam(o.Namespace).DefaultNamespace().AllNamespaces(o.AllNamespaces).
@@ -311,19 +415,30 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
LabelSelectorParam(o.LabelSelector).
FieldSelectorParam(o.FieldSelector).
ExportParam(o.Export).
RequestChunksOf(o.ChunkSize).
RequestChunksOf(chunkSize).
IncludeUninitialized(o.IncludeUninitialized).
ResourceTypeOrNameArgs(true, args...).
ContinueOnError().
Latest().
Flatten().
TransformRequests(func(req *rest.Request) {
if o.ServerPrint && o.IsHumanReadablePrinter && !o.Sort {
group := metav1beta1.GroupName
version := metav1beta1.SchemeGroupVersion.Version
// We need full objects if printing with openapi columns
if o.PrintWithOpenAPICols {
return
}
if !o.ServerPrint || !o.IsHumanReadablePrinter {
return
}
tableParam := fmt.Sprintf("application/json;as=Table;v=%s;g=%s, application/json", version, group)
req.SetHeader("Accept", tableParam)
group := metav1beta1.GroupName
version := metav1beta1.SchemeGroupVersion.Version
tableParam := fmt.Sprintf("application/json;as=Table;v=%s;g=%s, application/json", version, group)
req.SetHeader("Accept", tableParam)
// if sorting, ensure we receive the full object in order to introspect its fields via jsonpath
if o.Sort {
req.Param("includeObject", "Object")
}
}).
Do()
@@ -345,6 +460,7 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
if err != nil {
allErrs = append(allErrs, err)
}
printWithKind := multipleGVKsRequested(infos)
objs := make([]runtime.Object, len(infos))
for ix := range infos {
@@ -366,12 +482,14 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
if err != nil {
return err
}
var sorter *kubectl.RuntimeSort
if o.Sort && len(objs) > 1 {
// TODO: questionable
if sorter, err = kubectl.SortObjects(cmdutil.InternalVersionDecoder(), objs, sorting); err != nil {
var positioner OriginalPositioner
if o.Sort {
sorter := NewRuntimeSorter(objs, sorting)
if err := sorter.Sort(); err != nil {
return err
}
positioner = sorter
}
var printer printers.ResourcePrinter
@@ -381,8 +499,8 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
for ix := range objs {
var mapping *meta.RESTMapping
var info *resource.Info
if sorter != nil {
info = infos[sorter.OriginalPosition(ix)]
if positioner != nil {
info = infos[positioner.OriginalPosition(ix)]
mapping = info.Mapping
} else {
info = infos[ix]
@@ -400,6 +518,7 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
nonEmptyObjCount++
printWithNamespace := o.AllNamespaces
if mapping != nil && mapping.Scope.Name() == meta.RESTScopeNameRoot {
printWithNamespace = false
}
@@ -414,7 +533,7 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
fmt.Fprintln(o.ErrOut)
}
printer, err = o.ToPrinter(mapping, printWithNamespace)
printer, err = o.ToPrinter(mapping, printWithNamespace, printWithKind)
if err != nil {
if !errs.Has(err.Error()) {
errs.Insert(err.Error())
@@ -443,7 +562,7 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
}
}
w.Flush()
if nonEmptyObjCount == 0 && !o.IgnoreNotFound {
if nonEmptyObjCount == 0 && !o.IgnoreNotFound && len(allErrs) == 0 {
fmt.Fprintln(o.ErrOut, "No resources found.")
}
return utilerrors.NewAggregate(allErrs)
@@ -493,30 +612,13 @@ func (o *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string)
if err != nil {
return err
}
if len(infos) > 1 {
gvk := infos[0].Mapping.GroupVersionKind
uniqueGVKs := 1
// If requesting a resource count greater than a request's --chunk-size,
// we will end up making multiple requests to the server, with each
// request producing its own "Info" object. Although overall we are
// dealing with a single resource type, we will end up with multiple
// infos returned by the builder. To handle this case, only fail if we
// have at least one info with a different GVK than the others.
for _, info := range infos {
if info.Mapping.GroupVersionKind != gvk {
uniqueGVKs++
}
}
if uniqueGVKs > 1 {
return i18n.Errorf("watch is only supported on individual resources and resource collections - %d resources were found", uniqueGVKs)
}
if multipleGVKsRequested(infos) {
return i18n.Errorf("watch is only supported on individual resources and resource collections - more than 1 resources were found")
}
info := infos[0]
mapping := info.ResourceMapping()
printer, err := o.ToPrinter(mapping, o.AllNamespaces)
printer, err := o.ToPrinter(mapping, o.AllNamespaces, false)
if err != nil {
return err
}
@@ -570,9 +672,11 @@ func (o *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string)
}
first := true
intr := interrupt.New(nil, w.Stop)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
intr := interrupt.New(nil, cancel)
intr.Run(func() error {
_, err := watch.Until(0, w, func(e watch.Event) (bool, error) {
_, err := watchtools.UntilWithoutRetry(ctx, w, func(e watch.Event) (bool, error) {
if !isList && first {
// drop the initial watch event in the single resource case
first = false
@@ -581,8 +685,12 @@ func (o *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string)
// printing always takes the internal version, but the watch event uses externals
// TODO fix printing to use server-side or be version agnostic
internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
if err := printer.PrintObj(attemptToConvertToInternal(e.Object, legacyscheme.Scheme, internalGV), o.Out); err != nil {
objToPrint := e.Object
if o.IsHumanReadablePrinter {
internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
objToPrint = attemptToConvertToInternal(e.Object, legacyscheme.Scheme, internalGV)
}
if err := printer.PrintObj(objToPrint, o.Out); err != nil {
return false, err
}
return false, nil
@@ -596,7 +704,7 @@ func (o *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string)
func attemptToConvertToInternal(obj runtime.Object, converter runtime.ObjectConvertor, targetVersion schema.GroupVersion) runtime.Object {
internalObject, err := converter.ConvertToVersion(obj, targetVersion)
if err != nil {
glog.V(1).Infof("Unable to convert %T to %v: err", obj, targetVersion, err)
glog.V(1).Infof("Unable to convert %T to %v: %v", obj, targetVersion, err)
return obj
}
return internalObject
@@ -650,7 +758,7 @@ func (o *GetOptions) printGeneric(r *resource.Result) error {
return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs)))
}
printer, err := o.ToPrinter(nil, false)
printer, err := o.ToPrinter(nil, false, false)
if err != nil {
return err
}
@@ -727,6 +835,7 @@ func (o *GetOptions) printGeneric(r *resource.Result) error {
func addOpenAPIPrintColumnFlags(cmd *cobra.Command, opt *GetOptions) {
cmd.Flags().BoolVar(&opt.PrintWithOpenAPICols, useOpenAPIPrintColumnFlagLabel, opt.PrintWithOpenAPICols, "If true, use x-kubernetes-print-column metadata (if present) from the OpenAPI schema for displaying a resource.")
cmd.Flags().MarkDeprecated(useOpenAPIPrintColumnFlagLabel, "deprecated in favor of server-side printing")
}
func addServerPrintColumnFlags(cmd *cobra.Command, opt *GetOptions) {
@@ -750,3 +859,16 @@ func maybeWrapSortingPrinter(printer printers.ResourcePrinter, sortBy string) pr
}
return printer
}
func multipleGVKsRequested(infos []*resource.Info) bool {
if len(infos) < 2 {
return false
}
gvk := infos[0].Mapping.GroupVersionKind
for _, info := range infos {
if info.Mapping.GroupVersionKind != gvk {
return true
}
}
return false
}

View File

@@ -23,8 +23,8 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/printers"
)
@@ -35,7 +35,7 @@ type PrintFlags struct {
NamePrintFlags *genericclioptions.NamePrintFlags
CustomColumnsFlags *printers.CustomColumnsPrintFlags
HumanReadableFlags *HumanPrintFlags
TemplateFlags *printers.KubeTemplatePrintFlags
TemplateFlags *genericclioptions.KubeTemplatePrintFlags
NoHeaders *bool
OutputFormat *string
@@ -182,7 +182,7 @@ func NewGetPrintFlags() *PrintFlags {
JSONYamlPrintFlags: genericclioptions.NewJSONYamlPrintFlags(),
NamePrintFlags: genericclioptions.NewNamePrintFlags(""),
TemplateFlags: printers.NewKubeTemplatePrintFlags(),
TemplateFlags: genericclioptions.NewKubeTemplatePrintFlags(),
HumanReadableFlags: NewHumanPrintFlags(),
CustomColumnsFlags: printers.NewCustomColumnsPrintFlags(),

View File

@@ -19,6 +19,7 @@ package get
import (
"bytes"
encjson "encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
@@ -27,40 +28,36 @@ import (
"strings"
"testing"
apiapps "k8s.io/api/apps/v1"
apiautoscaling "k8s.io/api/autoscaling/v1"
apibatchv1 "k8s.io/api/batch/v1"
apibatchv1beta1 "k8s.io/api/batch/v1beta1"
api "k8s.io/api/core/v1"
apiextensionsv1beta1 "k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions/resource"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
restclientwatch "k8s.io/client-go/rest/watch"
"k8s.io/kube-openapi/pkg/util/proto"
apitesting "k8s.io/kubernetes/pkg/api/testing"
"k8s.io/kubernetes/pkg/apis/core/v1"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
openapitesting "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi/testing"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource"
"k8s.io/kubernetes/pkg/kubectl/scheme"
)
var openapiSchemaPath = filepath.Join("..", "..", "..", "..", "api", "openapi-spec", "swagger.json")
// This init should be removed after switching this command and its tests to user external types.
func init() {
api.AddToScheme(scheme.Scheme)
scheme.Scheme.AddConversionFuncs(v1.Convert_core_PodSpec_To_v1_PodSpec)
scheme.Scheme.AddConversionFuncs(v1.Convert_v1_PodSecurityContext_To_core_PodSecurityContext)
}
var unstructuredSerializer = resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer
func defaultHeader() http.Header {
@@ -226,7 +223,7 @@ func TestGetUnknownSchemaObject(t *testing.T) {
func TestGetSchemaObject(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(schema.GroupVersion{Version: "v1"})
codec := scheme.Codecs.LegacyCodec(schema.GroupVersion{Version: "v1"})
t.Logf("%v", string(runtime.EncodeOrDie(codec, &api.ReplicationController{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})))
tf.UnstructuredClient = &fake.RESTClient{
@@ -249,7 +246,7 @@ func TestGetObjectsWithOpenAPIOutputFormatPresent(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
// overide the openAPISchema function to return custom output
// for Pod type.
@@ -265,11 +262,11 @@ func TestGetObjectsWithOpenAPIOutputFormatPresent(t *testing.T) {
cmd.Flags().Set(useOpenAPIPrintColumnFlagLabel, "true")
cmd.Run(cmd, []string{"pods", "foo"})
expected := `NAME RSRC
foo 10
expected := `NAME RSRC
foo 10
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -305,7 +302,7 @@ func TestGetObjects(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -317,11 +314,11 @@ func TestGetObjects(t *testing.T) {
cmd.SetOutput(buf)
cmd.Run(cmd, []string{"pods", "foo"})
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -330,7 +327,7 @@ func TestGetObjectsShowKind(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -343,11 +340,70 @@ func TestGetObjectsShowKind(t *testing.T) {
cmd.Flags().Set("show-kind", "true")
cmd.Run(cmd, []string{"pods", "foo"})
expected := `NAME READY STATUS RESTARTS AGE
pod/foo 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
pod/foo 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
func TestGetMultipleResourceTypesShowKinds(t *testing.T) {
pods, svcs, _ := testData()
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])},
}
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
Client: fake.CreateHTTPClient(func(req *http.Request) (*http.Response, error) {
switch p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/pods" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, pods)}, nil
case p == "/namespaces/test/replicationcontrollers" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &api.ReplicationControllerList{})}, nil
case p == "/namespaces/test/services" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, svcs)}, nil
case p == "/namespaces/test/statefulsets" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &apiapps.StatefulSetList{})}, nil
case p == "/namespaces/test/horizontalpodautoscalers" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &apiautoscaling.HorizontalPodAutoscalerList{})}, nil
case p == "/namespaces/test/jobs" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &apibatchv1.JobList{})}, nil
case p == "/namespaces/test/cronjobs" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &apibatchv1beta1.CronJobList{})}, nil
case p == "/namespaces/test/daemonsets" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &apiapps.DaemonSetList{})}, nil
case p == "/namespaces/test/deployments" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &apiextensionsv1beta1.DeploymentList{})}, nil
case p == "/namespaces/test/replicasets" && m == "GET":
return &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &apiextensionsv1beta1.ReplicaSetList{})}, nil
default:
t.Fatalf("request url: %#v,and request: %#v", req.URL, req)
return nil, nil
}
}),
}
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdGet("kubectl", tf, streams)
cmd.SetOutput(buf)
cmd.Run(cmd, []string{"all"})
expected := `NAME READY STATUS RESTARTS AGE
pod/foo 0/0 0 <unknown>
pod/bar 0/0 0 <unknown>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/baz ClusterIP <none> <none> <none> <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -356,7 +412,7 @@ func TestGetObjectsShowLabels(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -369,11 +425,11 @@ func TestGetObjectsShowLabels(t *testing.T) {
cmd.Flags().Set("show-labels", "true")
cmd.Run(cmd, []string{"pods", "foo"})
expected := `NAME READY STATUS RESTARTS AGE LABELS
foo 0/0 0 <unknown> <none>
expected := `NAME READY STATUS RESTARTS AGE LABELS
foo 0/0 0 <unknown> <none>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -394,7 +450,7 @@ func TestGetObjectIgnoreNotFound(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -446,7 +502,7 @@ func TestGetSortedObjects(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -462,22 +518,166 @@ func TestGetSortedObjects(t *testing.T) {
cmd.Flags().Set("sort-by", ".metadata.name")
cmd.Run(cmd, []string{"pods"})
expected := `NAME READY STATUS RESTARTS AGE
a 0/0 0 <unknown>
b 0/0 0 <unknown>
c 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
a 0/0 0 <unknown>
b 0/0 0 <unknown>
c 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
func sortTestData() []runtime.Object {
return []runtime.Object{
&api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: "test", ResourceVersion: "10"},
Spec: apitesting.V1DeepEqualSafePodSpec(),
},
&api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "b", Namespace: "test", ResourceVersion: "11"},
Spec: apitesting.V1DeepEqualSafePodSpec(),
},
&api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "a", Namespace: "test", ResourceVersion: "9"},
Spec: apitesting.V1DeepEqualSafePodSpec(),
},
}
}
func sortTestTableData() []runtime.Object {
return []runtime.Object{
&metav1beta1.Table{
TypeMeta: metav1.TypeMeta{Kind: "Table"},
Rows: []metav1beta1.TableRow{
{
Object: runtime.RawExtension{
Object: &api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: "test", ResourceVersion: "10"},
Spec: apitesting.V1DeepEqualSafePodSpec(),
},
},
},
{
Object: runtime.RawExtension{
Object: &api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "b", Namespace: "test", ResourceVersion: "11"},
Spec: apitesting.V1DeepEqualSafePodSpec(),
},
},
},
{
Object: runtime.RawExtension{
Object: &api.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "a", Namespace: "test", ResourceVersion: "9"},
Spec: apitesting.V1DeepEqualSafePodSpec(),
},
},
},
},
},
}
}
func TestRuntimeSorter(t *testing.T) {
tests := []struct {
name string
field string
objs []runtime.Object
op func(sorter *RuntimeSorter, objs []runtime.Object, out io.Writer) error
expect string
expectError string
}{
{
name: "ensure sorter returns original position",
field: "metadata.name",
objs: sortTestData(),
op: func(sorter *RuntimeSorter, objs []runtime.Object, out io.Writer) error {
for idx := range objs {
p := sorter.OriginalPosition(idx)
fmt.Fprintf(out, "%v,", p)
}
return nil
},
expect: "2,1,0,",
},
{
name: "ensure sorter handles table object position",
field: "metadata.name",
objs: sortTestTableData(),
op: func(sorter *RuntimeSorter, objs []runtime.Object, out io.Writer) error {
for idx := range objs {
p := sorter.OriginalPosition(idx)
fmt.Fprintf(out, "%v,", p)
}
return nil
},
expect: "0,",
},
{
name: "ensure sorter sorts table objects",
field: "metadata.name",
objs: sortTestData(),
op: func(sorter *RuntimeSorter, objs []runtime.Object, out io.Writer) error {
for _, o := range objs {
fmt.Fprintf(out, "%s,", o.(*api.Pod).Name)
}
return nil
},
expect: "a,b,c,",
},
{
name: "ensure sorter rejects mixed Table + non-Table object lists",
field: "metadata.name",
objs: append(sortTestData(), sortTestTableData()...),
op: func(sorter *RuntimeSorter, objs []runtime.Object, out io.Writer) error { return nil },
expectError: "sorting is not supported on mixed Table",
},
{
name: "ensure sorter errors out on invalid jsonpath",
field: "metadata.unknown",
objs: sortTestData(),
op: func(sorter *RuntimeSorter, objs []runtime.Object, out io.Writer) error { return nil },
expectError: "couldn't find any field with path",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
sorter := NewRuntimeSorter(tc.objs, tc.field)
if err := sorter.Sort(); err != nil {
if len(tc.expectError) > 0 && strings.Contains(err.Error(), tc.expectError) {
return
}
if len(tc.expectError) > 0 {
t.Fatalf("unexpected error: expecting %s, but got %s", tc.expectError, err)
}
t.Fatalf("unexpected error: %v", err)
}
out := bytes.NewBuffer([]byte{})
err := tc.op(sorter, tc.objs, out)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if tc.expect != out.String() {
t.Fatalf("unexpected output: expecting %s, but got %s", tc.expect, out.String())
}
})
}
}
func TestGetObjectsIdentifiedByFile(t *testing.T) {
pods, _, _ := testData()
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -490,11 +690,11 @@ func TestGetObjectsIdentifiedByFile(t *testing.T) {
cmd.Flags().Set("filename", "../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml")
cmd.Run(cmd, []string{})
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -503,7 +703,7 @@ func TestGetListObjects(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -515,12 +715,12 @@ func TestGetListObjects(t *testing.T) {
cmd.SetOutput(buf)
cmd.Run(cmd, []string{"pods"})
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
bar 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
bar 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -529,7 +729,7 @@ func TestGetListComponentStatus(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -547,7 +747,7 @@ serverbad Unhealthy bad status: 500
serverunknown Unhealthy fizzbuzz error
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -569,7 +769,7 @@ func TestGetMixedGenericObjects(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -609,7 +809,7 @@ func TestGetMixedGenericObjects(t *testing.T) {
}
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -618,7 +818,7 @@ func TestGetMultipleTypeObjects(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -640,14 +840,14 @@ func TestGetMultipleTypeObjects(t *testing.T) {
cmd.SetOutput(buf)
cmd.Run(cmd, []string{"pods,services"})
expected := `NAME READY STATUS RESTARTS AGE
pod/foo 0/0 0 <unknown>
pod/bar 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
pod/foo 0/0 0 <unknown>
pod/bar 0/0 0 <unknown>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/baz ClusterIP <none> <none> <none> <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -656,7 +856,7 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -755,7 +955,7 @@ func TestGetMultipleTypeObjectsWithLabelSelector(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -782,14 +982,14 @@ func TestGetMultipleTypeObjectsWithLabelSelector(t *testing.T) {
cmd.Flags().Set("selector", "a=b")
cmd.Run(cmd, []string{"pods,services"})
expected := `NAME READY STATUS RESTARTS AGE
pod/foo 0/0 0 <unknown>
pod/bar 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
pod/foo 0/0 0 <unknown>
pod/bar 0/0 0 <unknown>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/baz ClusterIP <none> <none> <none> <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -798,7 +998,7 @@ func TestGetMultipleTypeObjectsWithFieldSelector(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -825,14 +1025,14 @@ func TestGetMultipleTypeObjectsWithFieldSelector(t *testing.T) {
cmd.Flags().Set("field-selector", "a=b")
cmd.Run(cmd, []string{"pods,services"})
expected := `NAME READY STATUS RESTARTS AGE
pod/foo 0/0 0 <unknown>
pod/bar 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
pod/foo 0/0 0 <unknown>
pod/bar 0/0 0 <unknown>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/baz ClusterIP <none> <none> <none> <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -846,7 +1046,7 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -871,11 +1071,11 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) {
expected := `NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/baz ClusterIP <none> <none> <none> <unknown>
NAME STATUS ROLES AGE VERSION
node/foo Unknown <none> <unknown>
NAME STATUS ROLES AGE VERSION
node/foo Unknown <none> <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -954,7 +1154,7 @@ func TestWatchLabelSelector(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
podList := &api.PodList{
Items: pods,
@@ -989,14 +1189,14 @@ func TestWatchLabelSelector(t *testing.T) {
cmd.Flags().Set("selector", "a=b")
cmd.Run(cmd, []string{"pods"})
expected := `NAME READY STATUS RESTARTS AGE
bar 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
bar 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -1005,7 +1205,7 @@ func TestWatchFieldSelector(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
podList := &api.PodList{
Items: pods,
@@ -1040,14 +1240,14 @@ func TestWatchFieldSelector(t *testing.T) {
cmd.Flags().Set("field-selector", "a=b")
cmd.Run(cmd, []string{"pods"})
expected := `NAME READY STATUS RESTARTS AGE
bar 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
bar 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -1056,7 +1256,7 @@ func TestWatchResource(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -1084,13 +1284,13 @@ func TestWatchResource(t *testing.T) {
cmd.Flags().Set("watch", "true")
cmd.Run(cmd, []string{"pods", "foo"})
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -1099,7 +1299,7 @@ func TestWatchResourceIdentifiedByFile(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -1128,13 +1328,13 @@ func TestWatchResourceIdentifiedByFile(t *testing.T) {
cmd.Flags().Set("filename", "../../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml")
cmd.Run(cmd, []string{})
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -1143,7 +1343,7 @@ func TestWatchOnlyResource(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
tf.UnstructuredClient = &fake.RESTClient{
NegotiatedSerializer: unstructuredSerializer,
@@ -1171,12 +1371,12 @@ func TestWatchOnlyResource(t *testing.T) {
cmd.Flags().Set("watch-only", "true")
cmd.Run(cmd, []string{"pods", "foo"})
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}
@@ -1185,7 +1385,7 @@ func TestWatchOnlyList(t *testing.T) {
tf := cmdtesting.NewTestFactory().WithNamespace("test")
defer tf.Cleanup()
codec := legacyscheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
codec := scheme.Codecs.LegacyCodec(scheme.Scheme.PrioritizedVersionsAllGroups()...)
podList := &api.PodList{
Items: pods,
@@ -1216,12 +1416,12 @@ func TestWatchOnlyList(t *testing.T) {
cmd.Flags().Set("watch-only", "true")
cmd.Run(cmd, []string{"pods"})
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
expected := `NAME READY STATUS RESTARTS AGE
foo 0/0 0 <unknown>
foo 0/0 0 <unknown>
`
if e, a := expected, buf.String(); e != a {
t.Errorf("expected %v, got %v", e, a)
t.Errorf("expected\n%v\ngot\n%v", e, a)
}
}

View File

@@ -18,7 +18,7 @@ package get
import (
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/kubectl/scheme"

View File

@@ -24,8 +24,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
)
func TestHumanReadablePrinterSupportsExpectedOptions(t *testing.T) {
@@ -61,7 +61,7 @@ func TestHumanReadablePrinterSupportsExpectedOptions(t *testing.T) {
{
name: "\"wide\" output format prints",
outputFormat: "wide",
expectedOutput: "NAME\\ +READY\\ +STATUS\\ +RESTARTS\\ +AGE\\ +IP\\ +NODE\nfoo\\ +0/0\\ +0\\ +<unknown>\\ +<none>\\ +<none>\n",
expectedOutput: "NAME\\ +READY\\ +STATUS\\ +RESTARTS\\ +AGE\\ +IP\\ +NODE\\ +NOMINATED NODE\nfoo\\ +0/0\\ +0\\ +<unknown>\\ +<none>\\ +<none>\\ +<none>\n",
},
{
name: "no-headers prints output with no headers",
@@ -72,7 +72,7 @@ func TestHumanReadablePrinterSupportsExpectedOptions(t *testing.T) {
name: "no-headers and a \"wide\" output format prints output with no headers and additional columns",
outputFormat: "wide",
noHeaders: true,
expectedOutput: "foo\\ +0/0\\ +0\\ +<unknown>\\ +<none>\\ +<none>\n",
expectedOutput: "foo\\ +0/0\\ +0\\ +<unknown>\\ +<none>\\ +<none>\\ +<none>\n",
},
{
name: "show-kind displays the resource's kind, even when printing a single type of resource",