mirror of https://github.com/k3s-io/k3s
Merge pull request #62881 from juanvallejo/jvallejo/wire-print-flags-get-cmd
Automatic merge from submit-queue (batch tested with PRs 61601, 62881, 63159). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. wire print flags through get.go **Release note**: ```release-note NONE ``` Adds the PrintFlags pattern to `get.go`. Prerequisite to ongoing server-side printing work. cc @soltysh @deads2kpull/8/head
commit
08d358e3d1
|
@ -149,6 +149,13 @@ package_group(
|
|||
],
|
||||
)
|
||||
|
||||
package_group(
|
||||
name = "pkg_kubectl_cmd_get_CONSUMERS",
|
||||
packages = [
|
||||
"//pkg/kubectl/cmd",
|
||||
],
|
||||
)
|
||||
|
||||
package_group(
|
||||
name = "pkg_kubectl_cmd_rollout_CONSUMERS",
|
||||
packages = [
|
||||
|
@ -177,7 +184,7 @@ package_group(
|
|||
"//pkg/kubectl/cmd/auth",
|
||||
"//pkg/kubectl/cmd/config",
|
||||
"//pkg/kubectl/cmd/create",
|
||||
"//pkg/kubectl/cmd/resource",
|
||||
"//pkg/kubectl/cmd/get",
|
||||
"//pkg/kubectl/cmd/rollout",
|
||||
"//pkg/kubectl/cmd/set",
|
||||
"//pkg/kubectl/cmd/templates",
|
||||
|
@ -199,7 +206,7 @@ package_group(
|
|||
"//pkg/kubectl/cmd",
|
||||
"//pkg/kubectl/cmd/auth",
|
||||
"//pkg/kubectl/cmd/create",
|
||||
"//pkg/kubectl/cmd/resource",
|
||||
"//pkg/kubectl/cmd/get",
|
||||
"//pkg/kubectl/cmd/rollout",
|
||||
"//pkg/kubectl/cmd/set",
|
||||
"//pkg/kubectl/explain",
|
||||
|
@ -233,7 +240,7 @@ package_group(
|
|||
"//pkg/kubectl/cmd/auth",
|
||||
"//pkg/kubectl/cmd/config",
|
||||
"//pkg/kubectl/cmd/create",
|
||||
"//pkg/kubectl/cmd/resource",
|
||||
"//pkg/kubectl/cmd/get",
|
||||
"//pkg/kubectl/cmd/rollout",
|
||||
"//pkg/kubectl/cmd/set",
|
||||
"//pkg/kubectl/cmd/testing",
|
||||
|
@ -303,7 +310,7 @@ package_group(
|
|||
"//pkg/kubectl/cmd/auth",
|
||||
"//pkg/kubectl/cmd/config",
|
||||
"//pkg/kubectl/cmd/create",
|
||||
"//pkg/kubectl/cmd/resource",
|
||||
"//pkg/kubectl/cmd/get",
|
||||
"//pkg/kubectl/cmd/rollout",
|
||||
"//pkg/kubectl/cmd/set",
|
||||
"//pkg/kubectl/cmd/testing",
|
||||
|
|
|
@ -139,6 +139,7 @@ pkg/kubectl/cmd
|
|||
pkg/kubectl/cmd/auth
|
||||
pkg/kubectl/cmd/config
|
||||
pkg/kubectl/cmd/create
|
||||
pkg/kubectl/cmd/get
|
||||
pkg/kubectl/cmd/rollout
|
||||
pkg/kubectl/cmd/set
|
||||
pkg/kubectl/cmd/templates
|
||||
|
|
|
@ -227,7 +227,7 @@ function wait-for-pods-with-label()
|
|||
{
|
||||
local i
|
||||
for i in $(seq 1 10); do
|
||||
kubeout=`kubectl get po -l $1 --template '{{range.items}}{{.metadata.name}}{{end}}' --sort-by metadata.name "${kube_flags[@]}"`
|
||||
kubeout=`kubectl get po -l $1 --output=go-template --template='{{range.items}}{{.metadata.name}}{{end}}' --sort-by metadata.name "${kube_flags[@]}"`
|
||||
if [[ $kubeout = $2 ]]; then
|
||||
return
|
||||
fi
|
||||
|
|
|
@ -69,7 +69,7 @@ go_library(
|
|||
"//pkg/kubectl/cmd/auth:go_default_library",
|
||||
"//pkg/kubectl/cmd/config:go_default_library",
|
||||
"//pkg/kubectl/cmd/create:go_default_library",
|
||||
"//pkg/kubectl/cmd/resource:go_default_library",
|
||||
"//pkg/kubectl/cmd/get:go_default_library",
|
||||
"//pkg/kubectl/cmd/rollout:go_default_library",
|
||||
"//pkg/kubectl/cmd/scalejob:go_default_library",
|
||||
"//pkg/kubectl/cmd/set:go_default_library",
|
||||
|
@ -190,7 +190,6 @@ go_test(
|
|||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/kubectl:go_default_library",
|
||||
"//pkg/kubectl/cmd/create:go_default_library",
|
||||
"//pkg/kubectl/cmd/resource: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",
|
||||
|
@ -201,7 +200,6 @@ go_test(
|
|||
"//pkg/kubectl/util/i18n:go_default_library",
|
||||
"//pkg/kubectl/util/term:go_default_library",
|
||||
"//pkg/printers:go_default_library",
|
||||
"//pkg/util/strings:go_default_library",
|
||||
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
"//vendor/gopkg.in/yaml.v2:go_default_library",
|
||||
|
@ -249,7 +247,7 @@ filegroup(
|
|||
"//pkg/kubectl/cmd/auth:all-srcs",
|
||||
"//pkg/kubectl/cmd/config:all-srcs",
|
||||
"//pkg/kubectl/cmd/create:all-srcs",
|
||||
"//pkg/kubectl/cmd/resource:all-srcs",
|
||||
"//pkg/kubectl/cmd/get:all-srcs",
|
||||
"//pkg/kubectl/cmd/rollout:all-srcs",
|
||||
"//pkg/kubectl/cmd/scalejob:all-srcs",
|
||||
"//pkg/kubectl/cmd/set:all-srcs",
|
||||
|
|
|
@ -27,7 +27,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl/cmd/auth"
|
||||
cmdconfig "k8s.io/kubernetes/pkg/kubectl/cmd/config"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/create"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/get"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/rollout"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
|
@ -264,8 +264,8 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
|
|||
{
|
||||
Message: "Basic Commands (Intermediate):",
|
||||
Commands: []*cobra.Command{
|
||||
resource.NewCmdGet(f, ioStreams),
|
||||
NewCmdExplain(f, ioStreams),
|
||||
get.NewCmdGet(f, ioStreams),
|
||||
NewCmdEdit(f, ioStreams),
|
||||
NewCmdDelete(f, out, err),
|
||||
},
|
||||
|
|
|
@ -19,7 +19,6 @@ package cmd
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
@ -35,18 +34,12 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/rest/fake"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/resource"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
"k8s.io/kubernetes/pkg/util/strings"
|
||||
)
|
||||
|
||||
// This init should be removed after switching this command and its tests to user external types.
|
||||
|
@ -244,78 +237,6 @@ func newAllPhasePodList() *api.PodList {
|
|||
}
|
||||
}
|
||||
|
||||
func Example_printServiceWithLabels() {
|
||||
tf := cmdtesting.NewTestFactory()
|
||||
defer tf.Cleanup()
|
||||
|
||||
ns := legacyscheme.Codecs
|
||||
|
||||
tf.Client = &fake.RESTClient{
|
||||
NegotiatedSerializer: ns,
|
||||
Client: nil,
|
||||
}
|
||||
cmd := resource.NewCmdGet(tf, genericclioptions.NewTestIOStreamsDiscard())
|
||||
svc := &api.ServiceList{
|
||||
Items: []api.Service{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "svc1",
|
||||
Namespace: "ns1",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().AddDate(-10, 0, 0)},
|
||||
Labels: map[string]string{
|
||||
"l1": "value",
|
||||
},
|
||||
},
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{Protocol: "UDP", Port: 53},
|
||||
{Protocol: "TCP", Port: 53},
|
||||
},
|
||||
Selector: map[string]string{
|
||||
"s": "magic",
|
||||
},
|
||||
ClusterIP: "10.1.1.1",
|
||||
Type: api.ServiceTypeClusterIP,
|
||||
},
|
||||
Status: api.ServiceStatus{},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "svc2",
|
||||
Namespace: "ns2",
|
||||
CreationTimestamp: metav1.Time{Time: time.Now().AddDate(-10, 0, 0)},
|
||||
Labels: map[string]string{
|
||||
"l1": "dolla-bill-yall",
|
||||
},
|
||||
},
|
||||
Spec: api.ServiceSpec{
|
||||
Ports: []api.ServicePort{
|
||||
{Protocol: "TCP", Port: 80},
|
||||
{Protocol: "TCP", Port: 8080},
|
||||
},
|
||||
Selector: map[string]string{
|
||||
"s": "kazam",
|
||||
},
|
||||
ClusterIP: "10.1.1.2",
|
||||
Type: api.ServiceTypeClusterIP,
|
||||
},
|
||||
Status: api.ServiceStatus{},
|
||||
}},
|
||||
}
|
||||
ld := strings.NewLineDelimiter(os.Stdout, "|")
|
||||
defer ld.Flush()
|
||||
cmd.Flags().Set("label-columns", "l1")
|
||||
err := cmdutil.PrintObject(cmd, svc, ld)
|
||||
if err != nil {
|
||||
fmt.Printf("Unexpected error: %v", err)
|
||||
}
|
||||
// Output:
|
||||
// |NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE L1|
|
||||
// |svc1 ClusterIP 10.1.1.1 <none> 53/UDP,53/TCP 10y value|
|
||||
// |svc2 ClusterIP 10.1.1.2 <none> 80/TCP,8080/TCP 10y dolla-bill-yall|
|
||||
// ||
|
||||
}
|
||||
|
||||
func TestNormalizationFuncGlobalExistence(t *testing.T) {
|
||||
// This test can be safely deleted when we will not support multiple flag formats
|
||||
root := NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, os.Stdout, os.Stderr)
|
||||
|
|
|
@ -1,9 +1,27 @@
|
|||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["get.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/resource",
|
||||
srcs = [
|
||||
"get.go",
|
||||
"get_flags.go",
|
||||
"humanreadable_flags.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/get",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
|
@ -13,8 +31,10 @@ go_library(
|
|||
"//pkg/kubectl/cmd/util/openapi:go_default_library",
|
||||
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||
"//pkg/kubectl/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",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||
|
@ -34,7 +54,10 @@ go_library(
|
|||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["get_test.go"],
|
||||
srcs = [
|
||||
"get_test.go",
|
||||
"humanreadable_flags_test.go",
|
||||
],
|
||||
data = [
|
||||
"//api/openapi-spec:swagger-spec",
|
||||
"//test/e2e/testing-manifests:all-srcs",
|
||||
|
@ -53,6 +76,7 @@ go_test(
|
|||
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
|
||||
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||
"//pkg/kubectl/scheme:go_default_library",
|
||||
"//pkg/printers: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/runtime:go_default_library",
|
||||
|
@ -68,17 +92,3 @@ go_test(
|
|||
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
package get
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
@ -52,6 +52,11 @@ import (
|
|||
|
||||
// GetOptions contains the input to the get command.
|
||||
type GetOptions struct {
|
||||
PrintFlags *PrintFlags
|
||||
ToPrinter func(*meta.RESTMapping, bool) (printers.ResourcePrinterFunc, error)
|
||||
IsGeneric bool
|
||||
PrintWithOpenAPICols bool
|
||||
|
||||
resource.FilenameOptions
|
||||
|
||||
Raw string
|
||||
|
@ -67,10 +72,9 @@ type GetOptions struct {
|
|||
|
||||
ServerPrint bool
|
||||
|
||||
NoHeaders bool
|
||||
Sort bool
|
||||
IgnoreNotFound bool
|
||||
ShowKind bool
|
||||
LabelColumns []string
|
||||
Export bool
|
||||
|
||||
IncludeUninitialized bool
|
||||
|
@ -129,7 +133,8 @@ const (
|
|||
// NewGetOptions returns a GetOptions with default chunk size 500.
|
||||
func NewGetOptions(streams genericclioptions.IOStreams) *GetOptions {
|
||||
return &GetOptions{
|
||||
ChunkSize: 500,
|
||||
PrintFlags: NewGetPrintFlags(),
|
||||
ChunkSize: 500,
|
||||
|
||||
IOStreams: streams,
|
||||
}
|
||||
|
@ -138,7 +143,7 @@ func NewGetOptions(streams genericclioptions.IOStreams) *GetOptions {
|
|||
// NewCmdGet creates a command object for the generic "get" action, which
|
||||
// retrieves one or more resources from a server.
|
||||
func NewCmdGet(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
options := NewGetOptions(streams)
|
||||
o := NewGetOptions(streams)
|
||||
validArgs := cmdutil.ValidArgList(f)
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
@ -148,77 +153,112 @@ func NewCmdGet(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Co
|
|||
Long: getLong + "\n\n" + cmdutil.ValidResourceTypeList(f),
|
||||
Example: getExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(options.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(options.Validate(cmd))
|
||||
cmdutil.CheckErr(options.Run(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate(cmd))
|
||||
cmdutil.CheckErr(o.Run(f, cmd, args))
|
||||
},
|
||||
SuggestFor: []string{"list", "ps"},
|
||||
ValidArgs: validArgs,
|
||||
ArgAliases: kubectl.ResourceAliases(validArgs),
|
||||
}
|
||||
|
||||
cmd.Flags().StringVar(&options.Raw, "raw", options.Raw, "Raw URI to request from the server. Uses the transport specified by the kubeconfig file.")
|
||||
cmd.Flags().BoolVarP(&options.Watch, "watch", "w", options.Watch, "After listing/getting the requested object, watch for changes. Uninitialized objects are excluded if no object name is provided.")
|
||||
cmd.Flags().BoolVar(&options.WatchOnly, "watch-only", options.WatchOnly, "Watch for changes to the requested object(s), without listing/getting first.")
|
||||
cmd.Flags().Int64Var(&options.ChunkSize, "chunk-size", options.ChunkSize, "Return large lists in chunks rather than all at once. Pass 0 to disable. This flag is beta and may change in the future.")
|
||||
cmd.Flags().BoolVar(&options.IgnoreNotFound, "ignore-not-found", options.IgnoreNotFound, "If the requested object does not exist the command will return exit code 0.")
|
||||
cmd.Flags().StringVarP(&options.LabelSelector, "selector", "l", options.LabelSelector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||
cmd.Flags().StringVar(&options.FieldSelector, "field-selector", options.FieldSelector, "Selector (field query) to filter on, supports '=', '==', and '!='.(e.g. --field-selector key1=value1,key2=value2). The server only supports a limited number of field queries per type.")
|
||||
cmd.Flags().BoolVar(&options.AllNamespaces, "all-namespaces", options.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
|
||||
o.PrintFlags.AddFlags(cmd)
|
||||
|
||||
cmd.Flags().StringVar(&o.Raw, "raw", o.Raw, "Raw URI to request from the server. Uses the transport specified by the kubeconfig file.")
|
||||
cmd.Flags().BoolVarP(&o.Watch, "watch", "w", o.Watch, "After listing/getting the requested object, watch for changes. Uninitialized objects are excluded if no object name is provided.")
|
||||
cmd.Flags().BoolVar(&o.WatchOnly, "watch-only", o.WatchOnly, "Watch for changes to the requested object(s), without listing/getting first.")
|
||||
cmd.Flags().Int64Var(&o.ChunkSize, "chunk-size", o.ChunkSize, "Return large lists in chunks rather than all at once. Pass 0 to disable. This flag is beta and may change in the future.")
|
||||
cmd.Flags().BoolVar(&o.IgnoreNotFound, "ignore-not-found", o.IgnoreNotFound, "If the requested object does not exist the command will return exit code 0.")
|
||||
cmd.Flags().StringVarP(&o.LabelSelector, "selector", "l", o.LabelSelector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||
cmd.Flags().StringVar(&o.FieldSelector, "field-selector", o.FieldSelector, "Selector (field query) to filter on, supports '=', '==', and '!='.(e.g. --field-selector key1=value1,key2=value2). The server only supports a limited number of field queries per type.")
|
||||
cmd.Flags().BoolVar(&o.AllNamespaces, "all-namespaces", o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
|
||||
cmdutil.AddIncludeUninitializedFlag(cmd)
|
||||
cmdutil.AddPrinterFlags(cmd)
|
||||
addOpenAPIPrintColumnFlags(cmd)
|
||||
addServerPrintColumnFlags(cmd)
|
||||
cmd.Flags().BoolVar(&options.ShowKind, "show-kind", options.ShowKind, "If present, list the resource type for the requested object(s).")
|
||||
cmd.Flags().StringSliceVarP(&options.LabelColumns, "label-columns", "L", options.LabelColumns, "Accepts a comma separated list of labels that are going to be presented as columns. Names are case-sensitive. You can also use multiple flag options like -L label1 -L label2...")
|
||||
cmd.Flags().BoolVar(&options.Export, "export", options.Export, "If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information.")
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, "identifying the resource to get from a server.")
|
||||
cmd.Flags().BoolVar(&o.Export, "export", o.Export, "If true, use 'export' for the resources. Exported resources are stripped of cluster-specific information.")
|
||||
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "identifying the resource to get from a server.")
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Complete takes the command arguments and factory and infers any remaining options.
|
||||
func (options *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
if len(options.Raw) > 0 {
|
||||
func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
if len(o.Raw) > 0 {
|
||||
if len(args) > 0 {
|
||||
return fmt.Errorf("arguments may not be passed when --raw is specified")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
options.ServerPrint = cmdutil.GetFlagBool(cmd, useServerPrintColumns)
|
||||
o.ServerPrint = cmdutil.GetFlagBool(cmd, useServerPrintColumns)
|
||||
|
||||
var err error
|
||||
options.Namespace, options.ExplicitNamespace, err = f.DefaultNamespace()
|
||||
o.Namespace, o.ExplicitNamespace, err = f.DefaultNamespace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if options.AllNamespaces {
|
||||
options.ExplicitNamespace = false
|
||||
if o.AllNamespaces {
|
||||
o.ExplicitNamespace = false
|
||||
}
|
||||
|
||||
isSorting, err := cmd.Flags().GetString("sort-by")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
options.Sort = len(isSorting) > 0
|
||||
o.Sort = len(isSorting) > 0
|
||||
|
||||
o.NoHeaders = cmdutil.GetFlagBool(cmd, "no-headers")
|
||||
|
||||
// TODO (soltysh): currently we don't support sorting and custom columns
|
||||
// with server side print. So in these cases force the old behavior.
|
||||
outputOption := cmd.Flags().Lookup("output").Value.String()
|
||||
if options.Sort && outputOption == "custom-columns" {
|
||||
options.ServerPrint = false
|
||||
if o.Sort && outputOption == "custom-columns" {
|
||||
o.ServerPrint = false
|
||||
}
|
||||
|
||||
options.IncludeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, false)
|
||||
// obtain printer here in order to determine if we are
|
||||
// printing humanreadable or generic output.
|
||||
printer, err := o.PrintFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.IsGeneric = printer.IsGeneric()
|
||||
|
||||
o.IncludeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, false)
|
||||
o.PrintWithOpenAPICols = cmdutil.GetFlagBool(cmd, useOpenAPIPrintColumnFlagLabel)
|
||||
|
||||
o.ToPrinter = func(mapping *meta.RESTMapping, withNamespace bool) (printers.ResourcePrinterFunc, error) {
|
||||
// make a new copy of current flags / opts before mutating
|
||||
printFlags := o.PrintFlags.Copy()
|
||||
|
||||
if mapping != nil {
|
||||
if !cmdSpecifiesOutputFmt(cmd) && o.PrintWithOpenAPICols {
|
||||
if apiSchema, err := f.OpenAPISchema(); err == nil {
|
||||
printFlags.UseOpenAPIColumns(apiSchema, mapping)
|
||||
}
|
||||
}
|
||||
if resource.MultipleTypesRequested(args) {
|
||||
printFlags.EnsureWithKind(mapping.GroupVersionKind.GroupKind())
|
||||
}
|
||||
}
|
||||
if withNamespace {
|
||||
printFlags.EnsureWithNamespace()
|
||||
}
|
||||
|
||||
printer, err := printFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return printer.PrintObj, nil
|
||||
}
|
||||
|
||||
switch {
|
||||
case options.Watch || options.WatchOnly:
|
||||
case o.Watch || o.WatchOnly:
|
||||
// include uninitialized objects when watching on a single object
|
||||
// unless explicitly set --include-uninitialized=false
|
||||
options.IncludeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, len(args) == 2)
|
||||
o.IncludeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, len(args) == 2)
|
||||
default:
|
||||
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(options.Filenames) {
|
||||
fmt.Fprintf(options.ErrOut, "You must specify the type of resource to get. %s\n\n", cmdutil.ValidResourceTypeList(f))
|
||||
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
|
||||
fmt.Fprintf(o.ErrOut, "You must specify the type of resource to get. %s\n\n", cmdutil.ValidResourceTypeList(f))
|
||||
fullCmdName := cmd.Parent().CommandPath()
|
||||
usageString := "Required resource not specified."
|
||||
if len(fullCmdName) > 0 && cmdutil.IsSiblingCommandExists(cmd, "explain") {
|
||||
|
@ -232,15 +272,15 @@ func (options *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
|
|||
}
|
||||
|
||||
// Validate checks the set of flags provided by the user.
|
||||
func (options *GetOptions) Validate(cmd *cobra.Command) error {
|
||||
if len(options.Raw) > 0 {
|
||||
if options.Watch || options.WatchOnly || len(options.LabelSelector) > 0 || options.Export {
|
||||
func (o *GetOptions) Validate(cmd *cobra.Command) error {
|
||||
if len(o.Raw) > 0 {
|
||||
if o.Watch || o.WatchOnly || len(o.LabelSelector) > 0 || o.Export {
|
||||
return fmt.Errorf("--raw may not be specified with other flags that filter the server request or alter the output")
|
||||
}
|
||||
if len(cmdutil.GetFlagString(cmd, "output")) > 0 {
|
||||
return cmdutil.UsageErrorf(cmd, "--raw and --output are mutually exclusive")
|
||||
}
|
||||
if _, err := url.ParseRequestURI(options.Raw); err != nil {
|
||||
if _, err := url.ParseRequestURI(o.Raw); err != nil {
|
||||
return cmdutil.UsageErrorf(cmd, "--raw must be a valid URL path: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -255,35 +295,29 @@ func (options *GetOptions) Validate(cmd *cobra.Command) error {
|
|||
|
||||
// Run performs the get operation.
|
||||
// TODO: remove the need to pass these arguments, like other commands.
|
||||
func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
if len(options.Raw) > 0 {
|
||||
return options.raw(f)
|
||||
func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
if len(o.Raw) > 0 {
|
||||
return o.raw(f)
|
||||
}
|
||||
if options.Watch || options.WatchOnly {
|
||||
return options.watch(f, cmd, args)
|
||||
}
|
||||
|
||||
printOpts := cmdutil.ExtractCmdPrintOptions(cmd, options.AllNamespaces)
|
||||
printer, err := cmdutil.PrinterForOptions(printOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
if o.Watch || o.WatchOnly {
|
||||
return o.watch(f, cmd, args)
|
||||
}
|
||||
|
||||
r := f.NewBuilder().
|
||||
Unstructured().
|
||||
NamespaceParam(options.Namespace).DefaultNamespace().AllNamespaces(options.AllNamespaces).
|
||||
FilenameParam(options.ExplicitNamespace, &options.FilenameOptions).
|
||||
LabelSelectorParam(options.LabelSelector).
|
||||
FieldSelectorParam(options.FieldSelector).
|
||||
ExportParam(options.Export).
|
||||
RequestChunksOf(options.ChunkSize).
|
||||
IncludeUninitialized(options.IncludeUninitialized).
|
||||
NamespaceParam(o.Namespace).DefaultNamespace().AllNamespaces(o.AllNamespaces).
|
||||
FilenameParam(o.ExplicitNamespace, &o.FilenameOptions).
|
||||
LabelSelectorParam(o.LabelSelector).
|
||||
FieldSelectorParam(o.FieldSelector).
|
||||
ExportParam(o.Export).
|
||||
RequestChunksOf(o.ChunkSize).
|
||||
IncludeUninitialized(o.IncludeUninitialized).
|
||||
ResourceTypeOrNameArgs(true, args...).
|
||||
ContinueOnError().
|
||||
Latest().
|
||||
Flatten().
|
||||
TransformRequests(func(req *rest.Request) {
|
||||
if options.ServerPrint && !printer.IsGeneric() && !options.Sort {
|
||||
if o.ServerPrint && !o.IsGeneric && !o.Sort {
|
||||
group := metav1beta1.GroupName
|
||||
version := metav1beta1.SchemeGroupVersion.Version
|
||||
|
||||
|
@ -293,15 +327,15 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
|
|||
}).
|
||||
Do()
|
||||
|
||||
if options.IgnoreNotFound {
|
||||
if o.IgnoreNotFound {
|
||||
r.IgnoreErrors(kapierrors.IsNotFound)
|
||||
}
|
||||
if err := r.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if printer.IsGeneric() {
|
||||
return options.printGeneric(printer, r)
|
||||
if o.IsGeneric {
|
||||
return o.printGeneric(r)
|
||||
}
|
||||
|
||||
allErrs := []error{}
|
||||
|
@ -313,8 +347,8 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
|
|||
|
||||
objs := make([]runtime.Object, len(infos))
|
||||
for ix := range infos {
|
||||
if options.ServerPrint {
|
||||
table, err := options.decodeIntoTable(cmdutil.InternalVersionJSONEncoder(), infos[ix].Object)
|
||||
if o.ServerPrint {
|
||||
table, err := o.decodeIntoTable(cmdutil.InternalVersionJSONEncoder(), infos[ix].Object)
|
||||
if err == nil {
|
||||
infos[ix].Object = table
|
||||
} else {
|
||||
|
@ -332,35 +366,26 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
|
|||
return err
|
||||
}
|
||||
var sorter *kubectl.RuntimeSort
|
||||
if options.Sort && len(objs) > 1 {
|
||||
if o.Sort && len(objs) > 1 {
|
||||
// TODO: questionable
|
||||
if sorter, err = kubectl.SortObjects(cmdutil.InternalVersionDecoder(), objs, sorting); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// use the default printer for each object
|
||||
printer = nil
|
||||
var printer printers.ResourcePrinter
|
||||
var lastMapping *meta.RESTMapping
|
||||
w := printers.GetNewTabWriter(options.Out)
|
||||
|
||||
useOpenAPIPrintColumns := cmdutil.GetFlagBool(cmd, useOpenAPIPrintColumnFlagLabel)
|
||||
|
||||
showKind := options.ShowKind || resource.MultipleTypesRequested(args) || cmdutil.MustPrintWithKinds(objs, infos, sorter)
|
||||
|
||||
noHeaders := cmdutil.GetFlagBool(cmd, "no-headers")
|
||||
nonEmptyObjCount := 0
|
||||
w := printers.GetNewTabWriter(o.Out)
|
||||
for ix := range objs {
|
||||
var mapping *meta.RESTMapping
|
||||
var original runtime.Object
|
||||
var info *resource.Info
|
||||
if sorter != nil {
|
||||
info = infos[sorter.OriginalPosition(ix)]
|
||||
mapping = info.Mapping
|
||||
original = info.Object
|
||||
} else {
|
||||
info = infos[ix]
|
||||
mapping = info.Mapping
|
||||
original = info.Object
|
||||
}
|
||||
|
||||
// if dealing with a table that has no rows, skip remaining steps
|
||||
|
@ -371,29 +396,24 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
|
|||
}
|
||||
}
|
||||
|
||||
nonEmptyObjCount++
|
||||
|
||||
printWithNamespace := o.AllNamespaces
|
||||
if mapping != nil && mapping.Scope.Name() == meta.RESTScopeNameRoot {
|
||||
printWithNamespace = false
|
||||
}
|
||||
|
||||
if shouldGetNewPrinterForMapping(printer, lastMapping, mapping) {
|
||||
if printer != nil {
|
||||
w.Flush()
|
||||
w.Flush()
|
||||
|
||||
// TODO: this doesn't belong here
|
||||
// add linebreak between resource groups (if there is more than one)
|
||||
// skip linebreak above first resource group
|
||||
if lastMapping != nil && !o.NoHeaders {
|
||||
fmt.Fprintln(o.ErrOut)
|
||||
}
|
||||
|
||||
printWithNamespace := options.AllNamespaces
|
||||
if mapping != nil && mapping.Scope.Name() == meta.RESTScopeNameRoot {
|
||||
printWithNamespace = false
|
||||
}
|
||||
|
||||
printOpts := cmdutil.ExtractCmdPrintOptions(cmd, printWithNamespace)
|
||||
// if cmd does not specify output format and useOpenAPIPrintColumnFlagLabel flag is true,
|
||||
// then get the default output options for this mapping from OpenAPI schema.
|
||||
if !cmdSpecifiesOutputFmt(cmd) && useOpenAPIPrintColumns {
|
||||
updatePrintOptionsForOpenAPI(f, mapping, printOpts)
|
||||
}
|
||||
|
||||
if showKind && mapping != nil {
|
||||
printOpts.WithKind = true
|
||||
printOpts.Kind = mapping.GroupVersionKind.GroupKind()
|
||||
}
|
||||
|
||||
printer, err = cmdutil.PrinterForOptions(printOpts)
|
||||
printer, err = o.ToPrinter(mapping, printWithNamespace)
|
||||
if err != nil {
|
||||
if !errs.Has(err.Error()) {
|
||||
errs.Insert(err.Error())
|
||||
|
@ -402,66 +422,33 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
|
|||
continue
|
||||
}
|
||||
|
||||
// TODO: this doesn't belong here
|
||||
// add linebreak between resource groups (if there is more than one)
|
||||
// skip linebreak above first resource group
|
||||
if lastMapping != nil && !noHeaders {
|
||||
fmt.Fprintf(options.ErrOut, "%s\n", "")
|
||||
}
|
||||
|
||||
lastMapping = mapping
|
||||
}
|
||||
|
||||
typedObj := info.AsInternal()
|
||||
|
||||
objToPrint := typedObj
|
||||
if printer.IsGeneric() {
|
||||
// use raw object as received from the builder when using generic
|
||||
// printer instead of decodedObj
|
||||
objToPrint = original
|
||||
}
|
||||
if err := printer.PrintObj(objToPrint, w); err != nil {
|
||||
if !errs.Has(err.Error()) {
|
||||
errs.Insert(err.Error())
|
||||
allErrs = append(allErrs, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
printer.PrintObj(info.AsInternal(), w)
|
||||
}
|
||||
w.Flush()
|
||||
nonEmptyObjCount := 0
|
||||
for _, obj := range objs {
|
||||
if table, ok := obj.(*metav1beta1.Table); ok {
|
||||
// exclude any Table objects with empty rows from our total object count
|
||||
if len(table.Rows) == 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
nonEmptyObjCount++
|
||||
}
|
||||
|
||||
if nonEmptyObjCount == 0 && !options.IgnoreNotFound {
|
||||
fmt.Fprintln(options.ErrOut, "No resources found.")
|
||||
if nonEmptyObjCount == 0 && !o.IgnoreNotFound {
|
||||
fmt.Fprintln(o.ErrOut, "No resources found.")
|
||||
}
|
||||
return utilerrors.NewAggregate(allErrs)
|
||||
}
|
||||
|
||||
// raw makes a simple HTTP request to the provided path on the server using the default
|
||||
// credentials.
|
||||
func (options *GetOptions) raw(f cmdutil.Factory) error {
|
||||
func (o *GetOptions) raw(f cmdutil.Factory) error {
|
||||
restClient, err := f.RESTClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
stream, err := restClient.Get().RequestURI(options.Raw).Stream()
|
||||
stream, err := restClient.Get().RequestURI(o.Raw).Stream()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stream.Close()
|
||||
|
||||
_, err = io.Copy(options.Out, stream)
|
||||
_, err = io.Copy(o.Out, stream)
|
||||
if err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
@ -470,16 +457,16 @@ func (options *GetOptions) raw(f cmdutil.Factory) error {
|
|||
|
||||
// watch starts a client-side watch of one or more resources.
|
||||
// TODO: remove the need for arguments here.
|
||||
func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
func (o *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
r := f.NewBuilder().
|
||||
Unstructured().
|
||||
NamespaceParam(options.Namespace).DefaultNamespace().AllNamespaces(options.AllNamespaces).
|
||||
FilenameParam(options.ExplicitNamespace, &options.FilenameOptions).
|
||||
LabelSelectorParam(options.LabelSelector).
|
||||
FieldSelectorParam(options.FieldSelector).
|
||||
ExportParam(options.Export).
|
||||
RequestChunksOf(options.ChunkSize).
|
||||
IncludeUninitialized(options.IncludeUninitialized).
|
||||
NamespaceParam(o.Namespace).DefaultNamespace().AllNamespaces(o.AllNamespaces).
|
||||
FilenameParam(o.ExplicitNamespace, &o.FilenameOptions).
|
||||
LabelSelectorParam(o.LabelSelector).
|
||||
FieldSelectorParam(o.FieldSelector).
|
||||
ExportParam(o.Export).
|
||||
RequestChunksOf(o.ChunkSize).
|
||||
IncludeUninitialized(o.IncludeUninitialized).
|
||||
ResourceTypeOrNameArgs(true, args...).
|
||||
SingleResourceType().
|
||||
Latest().
|
||||
|
@ -514,8 +501,7 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
|
|||
|
||||
info := infos[0]
|
||||
mapping := info.ResourceMapping()
|
||||
printOpts := cmdutil.ExtractCmdPrintOptions(cmd, options.AllNamespaces)
|
||||
printer, err := cmdutil.PrinterForOptions(printOpts)
|
||||
printer, err := o.ToPrinter(mapping, o.AllNamespaces)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -540,9 +526,9 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
|
|||
}
|
||||
|
||||
// print the current object
|
||||
if !options.WatchOnly {
|
||||
if !o.WatchOnly {
|
||||
var objsToPrint []runtime.Object
|
||||
writer := printers.GetNewTabWriter(options.Out)
|
||||
writer := printers.GetNewTabWriter(o.Out)
|
||||
|
||||
if isList {
|
||||
objsToPrint, _ = meta.ExtractList(obj)
|
||||
|
@ -550,10 +536,12 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
|
|||
objsToPrint = append(objsToPrint, obj)
|
||||
}
|
||||
for _, objToPrint := range objsToPrint {
|
||||
// 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(objToPrint, mapping, internalGV), writer); err != nil {
|
||||
if !o.IsGeneric {
|
||||
// printing always takes the internal version, but the watch event uses externals
|
||||
internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
|
||||
objToPrint = attemptToConvertToInternal(objToPrint, mapping, internalGV)
|
||||
}
|
||||
if err := printer.PrintObj(objToPrint, writer); err != nil {
|
||||
return fmt.Errorf("unable to output the provided object: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -579,7 +567,7 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
|
|||
// 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, mapping, internalGV), options.Out); err != nil {
|
||||
if err := printer.PrintObj(attemptToConvertToInternal(e.Object, mapping, internalGV), o.Out); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
|
@ -599,7 +587,7 @@ func attemptToConvertToInternal(obj runtime.Object, converter runtime.ObjectConv
|
|||
return internalObject
|
||||
}
|
||||
|
||||
func (options *GetOptions) decodeIntoTable(encoder runtime.Encoder, obj runtime.Object) (runtime.Object, error) {
|
||||
func (o *GetOptions) decodeIntoTable(encoder runtime.Encoder, obj runtime.Object) (runtime.Object, error) {
|
||||
if obj.GetObjectKind().GroupVersionKind().Kind != "Table" {
|
||||
return nil, fmt.Errorf("attempt to decode non-Table object into a v1beta1.Table")
|
||||
}
|
||||
|
@ -618,7 +606,7 @@ func (options *GetOptions) decodeIntoTable(encoder runtime.Encoder, obj runtime.
|
|||
return table, nil
|
||||
}
|
||||
|
||||
func (options *GetOptions) printGeneric(printer printers.ResourcePrinter, r *resource.Result) error {
|
||||
func (o *GetOptions) printGeneric(r *resource.Result) error {
|
||||
// we flattened the data from the builder, so we have individual items, but now we'd like to either:
|
||||
// 1. if there is more than one item, combine them all into a single list
|
||||
// 2. if there is a single item and that item is a list, leave it as its specific list
|
||||
|
@ -633,10 +621,15 @@ func (options *GetOptions) printGeneric(printer printers.ResourcePrinter, r *res
|
|||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
if len(infos) == 0 && options.IgnoreNotFound {
|
||||
if len(infos) == 0 && o.IgnoreNotFound {
|
||||
return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs)))
|
||||
}
|
||||
|
||||
printer, err := o.ToPrinter(nil, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var obj runtime.Object
|
||||
if !singleItemImplied || len(infos) > 1 {
|
||||
// we have more than one item, so coerce all items into a list.
|
||||
|
@ -694,13 +687,13 @@ func (options *GetOptions) printGeneric(printer printers.ResourcePrinter, r *res
|
|||
for _, item := range items {
|
||||
list.Items = append(list.Items, *item.(*unstructured.Unstructured))
|
||||
}
|
||||
if err := printer.PrintObj(list, options.Out); err != nil {
|
||||
if err := printer.PrintObj(list, o.Out); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
return utilerrors.Reduce(utilerrors.Flatten(utilerrors.NewAggregate(errs)))
|
||||
}
|
||||
|
||||
if printErr := printer.PrintObj(obj, options.Out); printErr != nil {
|
||||
if printErr := printer.PrintObj(obj, o.Out); printErr != nil {
|
||||
errs = append(errs, printErr)
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
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 get
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
)
|
||||
|
||||
// PrintFlags composes common printer flag structs
|
||||
// used in the Get command.
|
||||
type PrintFlags struct {
|
||||
JSONYamlPrintFlags *printers.JSONYamlPrintFlags
|
||||
NamePrintFlags *printers.NamePrintFlags
|
||||
TemplateFlags *printers.KubeTemplatePrintFlags
|
||||
CustomColumnsFlags *printers.CustomColumnsPrintFlags
|
||||
HumanReadableFlags *HumanPrintFlags
|
||||
|
||||
NoHeaders *bool
|
||||
OutputFormat *string
|
||||
}
|
||||
|
||||
// EnsureWithNamespace ensures that humanreadable flags return
|
||||
// a printer capable of printing with a "namespace" column.
|
||||
func (f *PrintFlags) EnsureWithNamespace() error {
|
||||
return f.HumanReadableFlags.EnsureWithNamespace()
|
||||
}
|
||||
|
||||
// EnsureWithKind ensures that humanreadable flags return
|
||||
// a printer capable of including resource kinds.
|
||||
func (f *PrintFlags) EnsureWithKind(kind schema.GroupKind) error {
|
||||
return f.HumanReadableFlags.EnsureWithKind(kind)
|
||||
}
|
||||
|
||||
// Copy returns a copy of PrintFlags for mutation
|
||||
func (f *PrintFlags) Copy() PrintFlags {
|
||||
printFlags := *f
|
||||
return printFlags
|
||||
}
|
||||
|
||||
// UseOpenAPIColumns modifies the output format, as well as the
|
||||
// "allowMissingKeys" option for template printers, to values
|
||||
// defined in the OpenAPI schema of a resource.
|
||||
func (f *PrintFlags) UseOpenAPIColumns(api openapi.Resources, mapping *meta.RESTMapping) error {
|
||||
// Found openapi metadata for this resource
|
||||
schema := api.LookupResource(mapping.GroupVersionKind)
|
||||
if schema == nil {
|
||||
// Schema not found, return empty columns
|
||||
return nil
|
||||
}
|
||||
|
||||
columns, found := openapi.GetPrintColumns(schema.GetExtensions())
|
||||
if !found {
|
||||
// Extension not found, return empty columns
|
||||
return nil
|
||||
}
|
||||
|
||||
parts := strings.SplitN(columns, "=", 2)
|
||||
if len(parts) < 2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
allowMissingKeys := true
|
||||
f.OutputFormat = &parts[0]
|
||||
f.TemplateFlags.TemplateArgument = &parts[1]
|
||||
f.TemplateFlags.AllowMissingKeys = &allowMissingKeys
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToPrinter attempts to find a composed set of PrintFlags suitable for
|
||||
// returning a printer based on current flag values.
|
||||
func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {
|
||||
outputFormat := ""
|
||||
if f.OutputFormat != nil {
|
||||
outputFormat = *f.OutputFormat
|
||||
}
|
||||
|
||||
noHeaders := false
|
||||
if f.NoHeaders != nil {
|
||||
noHeaders = *f.NoHeaders
|
||||
}
|
||||
f.HumanReadableFlags.NoHeaders = noHeaders
|
||||
f.CustomColumnsFlags.NoHeaders = noHeaders
|
||||
|
||||
if f.TemplateFlags.TemplateArgument != nil {
|
||||
f.CustomColumnsFlags.TemplateArgument = *f.TemplateFlags.TemplateArgument
|
||||
}
|
||||
|
||||
if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
if p, err := f.HumanReadableFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
if p, err := f.TemplateFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
if p, err := f.CustomColumnsFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) {
|
||||
return p, err
|
||||
}
|
||||
|
||||
return nil, printers.NoCompatiblePrinterError{Options: f}
|
||||
}
|
||||
|
||||
// AddFlags receives a *cobra.Command reference and binds
|
||||
// flags related to humanreadable and template printing.
|
||||
func (f *PrintFlags) AddFlags(cmd *cobra.Command) {
|
||||
f.JSONYamlPrintFlags.AddFlags(cmd)
|
||||
f.NamePrintFlags.AddFlags(cmd)
|
||||
f.TemplateFlags.AddFlags(cmd)
|
||||
f.HumanReadableFlags.AddFlags(cmd)
|
||||
f.CustomColumnsFlags.AddFlags(cmd)
|
||||
|
||||
if f.OutputFormat != nil {
|
||||
cmd.Flags().StringVarP(f.OutputFormat, "output", "o", *f.OutputFormat, "Output format. One of: json|yaml|wide|name|custom-columns=...|custom-columns-file=...|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=... See custom columns [http://kubernetes.io/docs/user-guide/kubectl-overview/#custom-columns], golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [http://kubernetes.io/docs/user-guide/jsonpath].")
|
||||
}
|
||||
if f.NoHeaders != nil {
|
||||
cmd.Flags().BoolVar(f.NoHeaders, "no-headers", *f.NoHeaders, "When using the default or custom-column output format, don't print headers (default print headers).")
|
||||
}
|
||||
|
||||
// TODO(juanvallejo): This is deprecated - remove
|
||||
cmd.Flags().BoolP("show-all", "a", true, "When printing, show all resources (default show all pods including terminated one.)")
|
||||
cmd.Flags().MarkDeprecated("show-all", "will be removed in an upcoming release")
|
||||
}
|
||||
|
||||
// NewGetPrintFlags returns flags associated with humanreadable,
|
||||
// template, and "name" printing, with default values set.
|
||||
func NewGetPrintFlags() *PrintFlags {
|
||||
outputFormat := ""
|
||||
noHeaders := false
|
||||
|
||||
return &PrintFlags{
|
||||
OutputFormat: &outputFormat,
|
||||
NoHeaders: &noHeaders,
|
||||
|
||||
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(),
|
||||
NamePrintFlags: printers.NewNamePrintFlags(""),
|
||||
TemplateFlags: printers.NewKubeTemplatePrintFlags(),
|
||||
HumanReadableFlags: NewHumanPrintFlags(),
|
||||
CustomColumnsFlags: printers.NewCustomColumnsPrintFlags(),
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package resource
|
||||
package get
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -513,7 +513,6 @@ func TestGetAllListObjects(t *testing.T) {
|
|||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
cmd := NewCmdGet(tf, streams)
|
||||
cmd.SetOutput(buf)
|
||||
cmd.Flags().Set("show-all", "true")
|
||||
cmd.Run(cmd, []string{"pods"})
|
||||
|
||||
expected := `NAME READY STATUS RESTARTS AGE
|
||||
|
@ -889,32 +888,6 @@ node/foo Unknown <none> <unknown>
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetByFormatForcesFlag(t *testing.T) {
|
||||
pods, _, _ := testData()
|
||||
|
||||
tf := cmdtesting.NewTestFactory()
|
||||
defer tf.Cleanup()
|
||||
codec := legacyscheme.Codecs.LegacyCodec(scheme.Versions...)
|
||||
|
||||
tf.UnstructuredClient = &fake.RESTClient{
|
||||
NegotiatedSerializer: unstructuredSerializer,
|
||||
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &pods.Items[0])},
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
cmd := NewCmdGet(tf, streams)
|
||||
cmd.SetOutput(buf)
|
||||
cmd.Flags().Lookup("output").Value.Set("yaml")
|
||||
cmd.Flags().Set("show-all", "false")
|
||||
cmd.Run(cmd, []string{"pods"})
|
||||
|
||||
showAllFlag, _ := cmd.Flags().GetBool("show-all")
|
||||
if showAllFlag {
|
||||
t.Error("expected showAll to not be true when getting resource")
|
||||
}
|
||||
}
|
||||
|
||||
func watchTestData() ([]api.Pod, []watch.Event) {
|
||||
pods := []api.Pod{
|
||||
{
|
|
@ -14,13 +14,15 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package printers
|
||||
package get
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
|
||||
)
|
||||
|
||||
// HumanPrintFlags provides default flags necessary for printing.
|
||||
|
@ -40,11 +42,28 @@ type HumanPrintFlags struct {
|
|||
WithNamespace bool
|
||||
}
|
||||
|
||||
// EnsureWithKind sets the provided GroupKind humanreadable value.
|
||||
// If the kind received is non-empty, the "showKind" humanreadable
|
||||
// printer option is set to true.
|
||||
func (f *HumanPrintFlags) EnsureWithKind(kind schema.GroupKind) error {
|
||||
showKind := !kind.Empty()
|
||||
|
||||
f.Kind = kind
|
||||
f.ShowKind = &showKind
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnsureWithNamespace sets the "WithNamespace" humanreadable option to true.
|
||||
func (f *HumanPrintFlags) EnsureWithNamespace() error {
|
||||
f.WithNamespace = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToPrinter receives an outputFormat and returns a printer capable of
|
||||
// handling human-readable output.
|
||||
func (f *HumanPrintFlags) ToPrinter(outputFormat string) (ResourcePrinter, bool, error) {
|
||||
func (f *HumanPrintFlags) ToPrinter(outputFormat string) (printers.ResourcePrinter, error) {
|
||||
if len(outputFormat) > 0 && outputFormat != "wide" {
|
||||
return nil, false, nil
|
||||
return nil, printers.NoCompatiblePrinterError{Options: f}
|
||||
}
|
||||
|
||||
encoder := scheme.Codecs.LegacyCodec(scheme.Registry.RegisteredGroupVersions()...)
|
||||
|
@ -65,7 +84,7 @@ func (f *HumanPrintFlags) ToPrinter(outputFormat string) (ResourcePrinter, bool,
|
|||
columnLabels = *f.ColumnLabels
|
||||
}
|
||||
|
||||
p := NewHumanReadablePrinter(encoder, decoder, PrintOptions{
|
||||
p := printers.NewHumanReadablePrinter(encoder, decoder, printers.PrintOptions{
|
||||
Kind: f.Kind,
|
||||
WithKind: showKind,
|
||||
NoHeaders: f.NoHeaders,
|
||||
|
@ -74,14 +93,11 @@ func (f *HumanPrintFlags) ToPrinter(outputFormat string) (ResourcePrinter, bool,
|
|||
ColumnLabels: columnLabels,
|
||||
ShowLabels: showLabels,
|
||||
})
|
||||
|
||||
// TODO(juanvallejo): enable this here once we wire commands to instantiate PrintFlags directly.
|
||||
// PrintHandlers are currently added through cmd/util/printing.go#PrinterForOptions
|
||||
//printersinternal.AddHandlers(p)
|
||||
printersinternal.AddHandlers(p)
|
||||
|
||||
// TODO(juanvallejo): handle sorting here
|
||||
|
||||
return p, true, nil
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// AddFlags receives a *cobra.Command reference and binds
|
||||
|
@ -103,19 +119,19 @@ func (f *HumanPrintFlags) AddFlags(c *cobra.Command) {
|
|||
|
||||
// NewHumanPrintFlags returns flags associated with
|
||||
// human-readable printing, with default values set.
|
||||
func NewHumanPrintFlags(kind schema.GroupKind, noHeaders, withNamespace, absoluteTimestamps bool) *HumanPrintFlags {
|
||||
func NewHumanPrintFlags() *HumanPrintFlags {
|
||||
showLabels := false
|
||||
sortBy := ""
|
||||
showKind := false
|
||||
columnLabels := []string{}
|
||||
|
||||
return &HumanPrintFlags{
|
||||
NoHeaders: noHeaders,
|
||||
WithNamespace: withNamespace,
|
||||
AbsoluteTimestamps: absoluteTimestamps,
|
||||
NoHeaders: false,
|
||||
WithNamespace: false,
|
||||
AbsoluteTimestamps: false,
|
||||
ColumnLabels: &columnLabels,
|
||||
|
||||
Kind: kind,
|
||||
Kind: schema.GroupKind{},
|
||||
ShowLabels: &showLabels,
|
||||
SortBy: &sortBy,
|
||||
ShowKind: &showKind,
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package printers_test
|
||||
package get
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -26,11 +26,15 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/printers"
|
||||
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
|
||||
)
|
||||
|
||||
func TestHumanReadablePrinterSupportsExpectedOptions(t *testing.T) {
|
||||
testObject := &api.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
|
||||
testObject := &api.Pod{ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "foo",
|
||||
Labels: map[string]string{
|
||||
"l1": "value",
|
||||
},
|
||||
}}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
@ -75,6 +79,11 @@ func TestHumanReadablePrinterSupportsExpectedOptions(t *testing.T) {
|
|||
showKind: true,
|
||||
expectedOutput: "NAME\\ +READY\\ +STATUS\\ +RESTARTS\\ +AGE\npod/foo\\ +0/0\\ +0\\ +<unknown>\n",
|
||||
},
|
||||
{
|
||||
name: "label-columns prints specified label values in new column",
|
||||
columnLabels: []string{"l1"},
|
||||
expectedOutput: "NAME\\ +READY\\ +STATUS\\ +RESTARTS\\ +AGE\\ +L1\nfoo\\ +0/0\\ +0\\ +<unknown>\\ +value\n",
|
||||
},
|
||||
{
|
||||
name: "withNamespace displays an additional NAMESPACE column",
|
||||
withNamespace: true,
|
||||
|
@ -94,7 +103,7 @@ func TestHumanReadablePrinterSupportsExpectedOptions(t *testing.T) {
|
|||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
printFlags := printers.HumanPrintFlags{
|
||||
printFlags := HumanPrintFlags{
|
||||
ShowKind: &tc.showKind,
|
||||
ShowLabels: &tc.showLabels,
|
||||
SortBy: &tc.sortBy,
|
||||
|
@ -108,14 +117,14 @@ func TestHumanReadablePrinterSupportsExpectedOptions(t *testing.T) {
|
|||
printFlags.Kind = schema.GroupKind{Kind: "pod"}
|
||||
}
|
||||
|
||||
p, matched, err := printFlags.ToPrinter(tc.outputFormat)
|
||||
p, err := printFlags.ToPrinter(tc.outputFormat)
|
||||
if tc.expectNoMatch {
|
||||
if matched {
|
||||
if !printers.IsNoCompatiblePrinterError(err) {
|
||||
t.Fatalf("expected no printer matches for output format %q", tc.outputFormat)
|
||||
}
|
||||
return
|
||||
}
|
||||
if !matched {
|
||||
if printers.IsNoCompatiblePrinterError(err) {
|
||||
t.Fatalf("expected to match template printer for output format %q", tc.outputFormat)
|
||||
}
|
||||
|
||||
|
@ -129,10 +138,6 @@ func TestHumanReadablePrinterSupportsExpectedOptions(t *testing.T) {
|
|||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// TODO(juanvallejo): remove this once we wire PrintFlags at the command level.
|
||||
// handlers should be attached to the printer inside of the ToPrinter method.
|
||||
printersinternal.AddHandlers(p.(*printers.HumanReadablePrinter))
|
||||
|
||||
out := bytes.NewBuffer([]byte{})
|
||||
err = p.PrintObj(testObject, out)
|
||||
if err != nil {
|
|
@ -13,7 +13,6 @@ go_library(
|
|||
"customcolumn_flags.go",
|
||||
"flags.go",
|
||||
"humanreadable.go",
|
||||
"humanreadable_flags.go",
|
||||
"interface.go",
|
||||
"json.go",
|
||||
"json_yaml_flags.go",
|
||||
|
@ -53,7 +52,6 @@ go_test(
|
|||
srcs = [
|
||||
"customcolumn_flags_test.go",
|
||||
"customcolumn_test.go",
|
||||
"humanreadable_flags_test.go",
|
||||
"json_yaml_flags_test.go",
|
||||
"jsonpath_flags_test.go",
|
||||
"name_flags_test.go",
|
||||
|
@ -63,11 +61,9 @@ go_test(
|
|||
":go_default_library",
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/printers/internalversion: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",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
)
|
||||
|
||||
|
@ -37,9 +38,9 @@ type CustomColumnsPrintFlags struct {
|
|||
// 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, bool, error) {
|
||||
func (f *CustomColumnsPrintFlags) ToPrinter(templateFormat string) (ResourcePrinter, error) {
|
||||
if len(templateFormat) == 0 {
|
||||
return nil, false, fmt.Errorf("missing output format")
|
||||
return nil, NoCompatiblePrinterError{}
|
||||
}
|
||||
|
||||
templateValue := ""
|
||||
|
@ -63,11 +64,11 @@ func (f *CustomColumnsPrintFlags) ToPrinter(templateFormat string) (ResourcePrin
|
|||
}
|
||||
|
||||
if _, supportedFormat := supportedFormats[templateFormat]; !supportedFormat {
|
||||
return nil, false, nil
|
||||
return nil, NoCompatiblePrinterError{}
|
||||
}
|
||||
|
||||
if len(templateValue) == 0 {
|
||||
return nil, true, fmt.Errorf("custom-columns format specified but no custom columns given")
|
||||
return nil, fmt.Errorf("custom-columns format specified but no custom columns given")
|
||||
}
|
||||
|
||||
decoder := scheme.Codecs.UniversalDecoder()
|
||||
|
@ -75,15 +76,15 @@ func (f *CustomColumnsPrintFlags) ToPrinter(templateFormat string) (ResourcePrin
|
|||
if templateFormat == "custom-columns-file" {
|
||||
file, err := os.Open(templateValue)
|
||||
if err != nil {
|
||||
return nil, true, fmt.Errorf("error reading template %s, %v\n", templateValue, err)
|
||||
return nil, fmt.Errorf("error reading template %s, %v\n", templateValue, err)
|
||||
}
|
||||
defer file.Close()
|
||||
p, err := NewCustomColumnsPrinterFromTemplate(file, decoder)
|
||||
return p, true, err
|
||||
return p, err
|
||||
}
|
||||
|
||||
p, err := NewCustomColumnsPrinterFromSpec(templateValue, decoder, f.NoHeaders)
|
||||
return p, true, err
|
||||
return NewVersionedPrinter(p, legacyscheme.Scheme, legacyscheme.Scheme, scheme.Versions...), err
|
||||
}
|
||||
|
||||
// AddFlags receives a *cobra.Command reference and binds
|
||||
|
@ -93,9 +94,9 @@ 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(noHeaders bool, templateValue string) *CustomColumnsPrintFlags {
|
||||
func NewCustomColumnsPrintFlags() *CustomColumnsPrintFlags {
|
||||
return &CustomColumnsPrintFlags{
|
||||
NoHeaders: noHeaders,
|
||||
TemplateArgument: templateValue,
|
||||
NoHeaders: false,
|
||||
TemplateArgument: "",
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,14 +98,14 @@ func TestPrinterSupportsExpectedCustomColumnFormats(t *testing.T) {
|
|||
TemplateArgument: tc.templateArg,
|
||||
}
|
||||
|
||||
p, matched, err := printFlags.ToPrinter(tc.outputFormat)
|
||||
p, err := printFlags.ToPrinter(tc.outputFormat)
|
||||
if tc.expectNoMatch {
|
||||
if matched {
|
||||
if !printers.IsNoCompatiblePrinterError(err) {
|
||||
t.Fatalf("expected no printer matches for output format %q", tc.outputFormat)
|
||||
}
|
||||
return
|
||||
}
|
||||
if !matched {
|
||||
if printers.IsNoCompatiblePrinterError(err) {
|
||||
t.Fatalf("expected to match template printer for output format %q", tc.outputFormat)
|
||||
}
|
||||
|
||||
|
|
|
@ -99,26 +99,6 @@ func TestVersionedPrinter(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPrintDefault(t *testing.T) {
|
||||
printerTests := []struct {
|
||||
Name string
|
||||
Format string
|
||||
}{
|
||||
{"test wide", "wide"},
|
||||
{"test blank format", ""},
|
||||
}
|
||||
|
||||
for _, test := range printerTests {
|
||||
printer, err := printers.GetStandardPrinter(nil, legacyscheme.Codecs.LegacyCodec(legacyscheme.Registry.RegisteredGroupVersions()...), []runtime.Decoder{legacyscheme.Codecs.UniversalDecoder(), unstructured.UnstructuredJSONScheme}, printers.PrintOptions{AllowMissingKeys: false})
|
||||
if err != nil {
|
||||
t.Errorf("in %s, unexpected error: %#v", test.Name, err)
|
||||
}
|
||||
if printer.IsGeneric() {
|
||||
t.Errorf("in %s, printer should not be generic: %#v", test.Name, printer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintUnstructuredObject(t *testing.T) {
|
||||
obj := &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
|
|
|
@ -75,37 +75,13 @@ func GetStandardPrinter(typer runtime.ObjectTyper, encoder runtime.Encoder, deco
|
|||
NoHeaders: options.NoHeaders,
|
||||
TemplateArgument: formatArgument,
|
||||
}
|
||||
customColumnsPrinter, matched, err := customColumnsFlags.ToPrinter(format)
|
||||
if !matched {
|
||||
return nil, fmt.Errorf("unable to match a name printer to handle current print options")
|
||||
}
|
||||
customColumnsPrinter, err := customColumnsFlags.ToPrinter(format)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
printer = customColumnsPrinter
|
||||
|
||||
case "wide":
|
||||
fallthrough
|
||||
case "":
|
||||
humanPrintFlags := NewHumanPrintFlags(options.Kind, options.NoHeaders, options.WithNamespace, options.AbsoluteTimestamps)
|
||||
|
||||
// TODO: these should be bound through a call to humanPrintFlags#AddFlags(cmd) once we instantiate PrintFlags at the command level
|
||||
humanPrintFlags.ShowKind = &options.WithKind
|
||||
humanPrintFlags.ShowLabels = &options.ShowLabels
|
||||
humanPrintFlags.ColumnLabels = &options.ColumnLabels
|
||||
humanPrintFlags.SortBy = &options.SortBy
|
||||
|
||||
humanPrinter, matches, err := humanPrintFlags.ToPrinter(format)
|
||||
if !matches {
|
||||
return nil, fmt.Errorf("unable to match a printer to handle current print options")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
printer = humanPrinter
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("output format %q not recognized", format)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue