mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 21:47:07 +00:00
remove printer helpers
This commit is contained in:
parent
d7d4381961
commit
5a34e4f594
@ -90,8 +90,10 @@ func NewCmdApiResources(f cmdutil.Factory, ioStreams genericclioptions.IOStreams
|
|||||||
cmdutil.CheckErr(o.RunApiResources(cmd, f))
|
cmdutil.CheckErr(o.RunApiResources(cmd, f))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdutil.AddOutputFlags(cmd)
|
|
||||||
cmdutil.AddNoHeadersFlags(cmd)
|
cmd.Flags().Bool("no-headers", false, "When using the default or custom-column output format, don't print headers (default print headers).")
|
||||||
|
cmd.Flags().StringP("output", "o", "", "Output format. One of: wide|name.")
|
||||||
|
|
||||||
cmd.Flags().StringVar(&o.APIGroup, "api-group", "", "Limit to resources in the specified API group.")
|
cmd.Flags().StringVar(&o.APIGroup, "api-group", "", "Limit to resources in the specified API group.")
|
||||||
cmd.Flags().BoolVar(&o.Namespaced, "namespaced", true, "Namespaced indicates if a resource is namespaced or not.")
|
cmd.Flags().BoolVar(&o.Namespaced, "namespaced", true, "Namespaced indicates if a resource is namespaced or not.")
|
||||||
cmd.Flags().StringSliceVar(&o.Verbs, "verbs", o.Verbs, "Limit to resources that support the specified verbs.")
|
cmd.Flags().StringSliceVar(&o.Verbs, "verbs", o.Verbs, "Limit to resources that support the specified verbs.")
|
||||||
|
@ -102,8 +102,9 @@ func NewCmdApplySetLastApplied(f cmdutil.Factory, ioStreams genericclioptions.IO
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o.PrintFlags.AddFlags(cmd)
|
||||||
|
|
||||||
cmdutil.AddDryRunFlag(cmd)
|
cmdutil.AddDryRunFlag(cmd)
|
||||||
cmdutil.AddPrinterFlags(cmd)
|
|
||||||
cmd.Flags().BoolVar(&o.CreateAnnotation, "create-annotation", o.CreateAnnotation, "Will create 'last-applied-configuration' annotations if current objects doesn't have one")
|
cmd.Flags().BoolVar(&o.CreateAnnotation, "create-annotation", o.CreateAnnotation, "Will create 'last-applied-configuration' annotations if current objects doesn't have one")
|
||||||
kubectl.AddJsonFilenameFlag(cmd, &o.FilenameOptions.Filenames, "Filename, directory, or URL to files that contains the last-applied-configuration annotations")
|
kubectl.AddJsonFilenameFlag(cmd, &o.FilenameOptions.Filenames, "Filename, directory, or URL to files that contains the last-applied-configuration annotations")
|
||||||
|
|
||||||
|
@ -1121,7 +1121,7 @@ func TestRunApplySetLastApplied(t *testing.T) {
|
|||||||
name: "set with exist object",
|
name: "set with exist object",
|
||||||
filePath: filenameRC,
|
filePath: filenameRC,
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
expectedOut: "replicationcontroller/test-rc configured\n",
|
expectedOut: "replicationcontroller/test-rc\n",
|
||||||
output: "name",
|
output: "name",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -1142,14 +1142,14 @@ func TestRunApplySetLastApplied(t *testing.T) {
|
|||||||
name: "set with exist object output json",
|
name: "set with exist object output json",
|
||||||
filePath: filenameRCJSON,
|
filePath: filenameRCJSON,
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
expectedOut: "replicationcontroller/test-rc configured\n",
|
expectedOut: "replicationcontroller/test-rc\n",
|
||||||
output: "name",
|
output: "name",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "set test for a directory of files",
|
name: "set test for a directory of files",
|
||||||
filePath: dirName,
|
filePath: dirName,
|
||||||
expectedErr: "",
|
expectedErr: "",
|
||||||
expectedOut: "replicationcontroller/test-rc configured\nreplicationcontroller/test-rc configured\n",
|
expectedOut: "replicationcontroller/test-rc\nreplicationcontroller/test-rc\n",
|
||||||
output: "name",
|
output: "name",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,9 @@ go_library(
|
|||||||
"//pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion:go_default_library",
|
"//pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion:go_default_library",
|
||||||
"//pkg/kubectl/cmd/templates:go_default_library",
|
"//pkg/kubectl/cmd/templates:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
"//pkg/kubectl/resource:go_default_library",
|
"//pkg/kubectl/resource:go_default_library",
|
||||||
|
"//pkg/printers:go_default_library",
|
||||||
"//pkg/registry/rbac/reconciliation:go_default_library",
|
"//pkg/registry/rbac/reconciliation:go_default_library",
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
|
@ -17,24 +17,23 @@ limitations under the License.
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
|
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdAuth(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
func NewCmdAuth(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
// Parent command to which all subcommands are added.
|
// Parent command to which all subcommands are added.
|
||||||
cmds := &cobra.Command{
|
cmds := &cobra.Command{
|
||||||
Use: "auth",
|
Use: "auth",
|
||||||
Short: "Inspect authorization",
|
Short: "Inspect authorization",
|
||||||
Long: `Inspect authorization`,
|
Long: `Inspect authorization`,
|
||||||
Run: cmdutil.DefaultSubCommandRun(errOut),
|
Run: cmdutil.DefaultSubCommandRun(streams.ErrOut),
|
||||||
}
|
}
|
||||||
|
|
||||||
cmds.AddCommand(NewCmdCanI(f, out, errOut))
|
cmds.AddCommand(NewCmdCanI(f, streams))
|
||||||
cmds.AddCommand(NewCmdReconcile(f, out, errOut))
|
cmds.AddCommand(NewCmdReconcile(f, streams))
|
||||||
|
|
||||||
return cmds
|
return cmds
|
||||||
}
|
}
|
||||||
|
@ -19,12 +19,12 @@ package auth
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
@ -48,8 +48,7 @@ type CanIOptions struct {
|
|||||||
Subresource string
|
Subresource string
|
||||||
ResourceName string
|
ResourceName string
|
||||||
|
|
||||||
Out io.Writer
|
genericclioptions.IOStreams
|
||||||
Err io.Writer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -81,10 +80,9 @@ var (
|
|||||||
kubectl auth can-i get /logs/`)
|
kubectl auth can-i get /logs/`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdCanI(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
|
func NewCmdCanI(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
o := &CanIOptions{
|
o := &CanIOptions{
|
||||||
Out: out,
|
IOStreams: streams,
|
||||||
Err: err,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
@ -232,9 +230,9 @@ func (o *CanIOptions) resourceFor(mapper meta.RESTMapper, resourceArg string) sc
|
|||||||
gvr, err = mapper.ResourceFor(groupResource.WithVersion(""))
|
gvr, err = mapper.ResourceFor(groupResource.WithVersion(""))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if len(groupResource.Group) == 0 {
|
if len(groupResource.Group) == 0 {
|
||||||
fmt.Fprintf(o.Err, "Warning: the server doesn't have a resource type '%s'\n", groupResource.Resource)
|
fmt.Fprintf(o.ErrOut, "Warning: the server doesn't have a resource type '%s'\n", groupResource.Resource)
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(o.Err, "Warning: the server doesn't have a resource type '%s' in group '%s'\n", groupResource.Resource, groupResource.Group)
|
fmt.Fprintf(o.ErrOut, "Warning: the server doesn't have a resource type '%s' in group '%s'\n", groupResource.Resource, groupResource.Group)
|
||||||
}
|
}
|
||||||
return schema.GroupVersionResource{Resource: resourceArg}
|
return schema.GroupVersionResource{Resource: resourceArg}
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ func TestRunAccessCheck(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
test.o.Out = ioutil.Discard
|
test.o.Out = ioutil.Discard
|
||||||
test.o.Err = ioutil.Discard
|
test.o.ErrOut = ioutil.Discard
|
||||||
|
|
||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
|
@ -18,7 +18,6 @@ package auth
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -29,21 +28,25 @@ import (
|
|||||||
internalrbacclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion"
|
internalrbacclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/rbac/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
"k8s.io/kubernetes/pkg/registry/rbac/reconciliation"
|
"k8s.io/kubernetes/pkg/registry/rbac/reconciliation"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReconcileOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
// ReconcileOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
|
||||||
// referencing the cmd.Flags()
|
// referencing the cmd.Flags()
|
||||||
type ReconcileOptions struct {
|
type ReconcileOptions struct {
|
||||||
|
PrintFlags *printers.PrintFlags
|
||||||
|
FilenameOptions *resource.FilenameOptions
|
||||||
|
|
||||||
Visitor resource.Visitor
|
Visitor resource.Visitor
|
||||||
RBACClient internalrbacclient.RbacInterface
|
RBACClient internalrbacclient.RbacInterface
|
||||||
NamespaceClient internalcoreclient.NamespaceInterface
|
NamespaceClient internalcoreclient.NamespaceInterface
|
||||||
|
|
||||||
Print func(*resource.Info) error
|
PrintObject printers.ResourcePrinterFunc
|
||||||
|
|
||||||
Out io.Writer
|
genericclioptions.IOStreams
|
||||||
Err io.Writer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -57,12 +60,16 @@ var (
|
|||||||
kubectl auth reconcile -f my-rbac-rules.yaml`)
|
kubectl auth reconcile -f my-rbac-rules.yaml`)
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdReconcile(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
|
func NewReconcileOptions(ioStreams genericclioptions.IOStreams) *ReconcileOptions {
|
||||||
fileOptions := &resource.FilenameOptions{}
|
return &ReconcileOptions{
|
||||||
o := &ReconcileOptions{
|
FilenameOptions: &resource.FilenameOptions{},
|
||||||
Out: out,
|
PrintFlags: printers.NewPrintFlags("reconciled"),
|
||||||
Err: err,
|
IOStreams: ioStreams,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCmdReconcile(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
|
o := NewReconcileOptions(streams)
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "reconcile -f FILENAME",
|
Use: "reconcile -f FILENAME",
|
||||||
@ -71,21 +78,21 @@ func NewCmdReconcile(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
|
|||||||
Long: reconcileLong,
|
Long: reconcileLong,
|
||||||
Example: reconcileExample,
|
Example: reconcileExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(o.Complete(cmd, f, args, fileOptions))
|
cmdutil.CheckErr(o.Complete(cmd, f, args))
|
||||||
cmdutil.CheckErr(o.Validate())
|
cmdutil.CheckErr(o.Validate())
|
||||||
cmdutil.CheckErr(o.RunReconcile())
|
cmdutil.CheckErr(o.RunReconcile())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdutil.AddPrinterFlags(cmd)
|
o.PrintFlags.AddFlags(cmd)
|
||||||
usage := "identifying the resource to reconcile."
|
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, fileOptions, usage)
|
cmdutil.AddFilenameOptionFlags(cmd, o.FilenameOptions, "identifying the resource to reconcile.")
|
||||||
cmd.MarkFlagRequired("filename")
|
cmd.MarkFlagRequired("filename")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args []string, options *resource.FilenameOptions) error {
|
func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args []string) error {
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
return errors.New("no arguments are allowed")
|
return errors.New("no arguments are allowed")
|
||||||
}
|
}
|
||||||
@ -99,7 +106,7 @@ func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args
|
|||||||
WithScheme(legacyscheme.Scheme).
|
WithScheme(legacyscheme.Scheme).
|
||||||
ContinueOnError().
|
ContinueOnError().
|
||||||
NamespaceParam(namespace).DefaultNamespace().
|
NamespaceParam(namespace).DefaultNamespace().
|
||||||
FilenameParam(enforceNamespace, options).
|
FilenameParam(enforceNamespace, o.FilenameOptions).
|
||||||
Flatten().
|
Flatten().
|
||||||
Do()
|
Do()
|
||||||
|
|
||||||
@ -115,17 +122,12 @@ func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args
|
|||||||
o.RBACClient = client.Rbac()
|
o.RBACClient = client.Rbac()
|
||||||
o.NamespaceClient = client.Core().Namespaces()
|
o.NamespaceClient = client.Core().Namespaces()
|
||||||
|
|
||||||
dryRun := false
|
printer, err := o.PrintFlags.ToPrinter()
|
||||||
output := cmdutil.GetFlagString(cmd, "output")
|
if err != nil {
|
||||||
shortOutput := output == "name"
|
return err
|
||||||
o.Print = func(info *resource.Info) error {
|
|
||||||
if len(output) > 0 && !shortOutput {
|
|
||||||
return cmdutil.PrintObject(cmd, info.Object, o.Out)
|
|
||||||
}
|
|
||||||
cmdutil.PrintSuccess(shortOutput, o.Out, info.Object, dryRun, "reconciled")
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
o.PrintObject = printer.PrintObj
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,13 +141,13 @@ func (o *ReconcileOptions) Validate() error {
|
|||||||
if o.NamespaceClient == nil {
|
if o.NamespaceClient == nil {
|
||||||
return errors.New("ReconcileOptions.NamespaceClient must be set")
|
return errors.New("ReconcileOptions.NamespaceClient must be set")
|
||||||
}
|
}
|
||||||
if o.Print == nil {
|
if o.PrintObject == nil {
|
||||||
return errors.New("ReconcileOptions.Print must be set")
|
return errors.New("ReconcileOptions.Print must be set")
|
||||||
}
|
}
|
||||||
if o.Out == nil {
|
if o.Out == nil {
|
||||||
return errors.New("ReconcileOptions.Out must be set")
|
return errors.New("ReconcileOptions.Out must be set")
|
||||||
}
|
}
|
||||||
if o.Err == nil {
|
if o.ErrOut == nil {
|
||||||
return errors.New("ReconcileOptions.Err must be set")
|
return errors.New("ReconcileOptions.Err must be set")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -157,10 +159,6 @@ func (o *ReconcileOptions) RunReconcile() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// shallowInfoCopy this is used to later twiddle the Object for printing
|
|
||||||
// we really need more straightforward printing options
|
|
||||||
shallowInfoCopy := *info
|
|
||||||
|
|
||||||
switch t := info.Object.(type) {
|
switch t := info.Object.(type) {
|
||||||
case *rbac.Role:
|
case *rbac.Role:
|
||||||
reconcileOptions := reconciliation.ReconcileRoleOptions{
|
reconcileOptions := reconciliation.ReconcileRoleOptions{
|
||||||
@ -176,8 +174,7 @@ func (o *ReconcileOptions) RunReconcile() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
shallowInfoCopy.Object = result.Role.GetObject()
|
o.PrintObject(result.Role.GetObject(), o.Out)
|
||||||
o.Print(&shallowInfoCopy)
|
|
||||||
|
|
||||||
case *rbac.ClusterRole:
|
case *rbac.ClusterRole:
|
||||||
reconcileOptions := reconciliation.ReconcileRoleOptions{
|
reconcileOptions := reconciliation.ReconcileRoleOptions{
|
||||||
@ -192,8 +189,7 @@ func (o *ReconcileOptions) RunReconcile() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
shallowInfoCopy.Object = result.Role.GetObject()
|
o.PrintObject(result.Role.GetObject(), o.Out)
|
||||||
o.Print(&shallowInfoCopy)
|
|
||||||
|
|
||||||
case *rbac.RoleBinding:
|
case *rbac.RoleBinding:
|
||||||
reconcileOptions := reconciliation.ReconcileRoleBindingOptions{
|
reconcileOptions := reconciliation.ReconcileRoleBindingOptions{
|
||||||
@ -209,8 +205,7 @@ func (o *ReconcileOptions) RunReconcile() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
shallowInfoCopy.Object = result.RoleBinding.GetObject()
|
o.PrintObject(result.RoleBinding.GetObject(), o.Out)
|
||||||
o.Print(&shallowInfoCopy)
|
|
||||||
|
|
||||||
case *rbac.ClusterRoleBinding:
|
case *rbac.ClusterRoleBinding:
|
||||||
reconcileOptions := reconciliation.ReconcileRoleBindingOptions{
|
reconcileOptions := reconciliation.ReconcileRoleBindingOptions{
|
||||||
@ -225,8 +220,7 @@ func (o *ReconcileOptions) RunReconcile() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
shallowInfoCopy.Object = result.RoleBinding.GetObject()
|
o.PrintObject(result.RoleBinding.GetObject(), o.Out)
|
||||||
o.Print(&shallowInfoCopy)
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
glog.V(1).Infof("skipping %#v", info.Object.GetObjectKind())
|
glog.V(1).Infof("skipping %#v", info.Object.GetObjectKind())
|
||||||
|
@ -123,8 +123,10 @@ func NewCmdCertificateApprove(f cmdutil.Factory, ioStreams genericclioptions.IOS
|
|||||||
cmdutil.CheckErr(options.RunCertificateApprove(cmdutil.GetFlagBool(cmd, "force")))
|
cmdutil.CheckErr(options.RunCertificateApprove(cmdutil.GetFlagBool(cmd, "force")))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.PrintFlags.AddFlags(cmd)
|
||||||
|
|
||||||
cmd.Flags().Bool("force", false, "Update the CSR even if it is already approved.")
|
cmd.Flags().Bool("force", false, "Update the CSR even if it is already approved.")
|
||||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, "identifying the resource to update")
|
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, "identifying the resource to update")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
@ -173,8 +175,10 @@ func NewCmdCertificateDeny(f cmdutil.Factory, ioStreams genericclioptions.IOStre
|
|||||||
cmdutil.CheckErr(options.RunCertificateDeny(cmdutil.GetFlagBool(cmd, "force")))
|
cmdutil.CheckErr(options.RunCertificateDeny(cmdutil.GetFlagBool(cmd, "force")))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.PrintFlags.AddFlags(cmd)
|
||||||
|
|
||||||
cmd.Flags().Bool("force", false, "Update the CSR even if it is already denied.")
|
cmd.Flags().Bool("force", false, "Update the CSR even if it is already denied.")
|
||||||
cmdutil.AddOutputFlagsForMutation(cmd)
|
|
||||||
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, "identifying the resource to update")
|
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, "identifying the resource to update")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -309,7 +309,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
NewCmdPortForward(f, out, err),
|
NewCmdPortForward(f, out, err),
|
||||||
NewCmdProxy(f, out),
|
NewCmdProxy(f, out),
|
||||||
NewCmdCp(f, ioStreams),
|
NewCmdCp(f, ioStreams),
|
||||||
auth.NewCmdAuth(f, out, err),
|
auth.NewCmdAuth(f, ioStreams),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -355,7 +355,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmds.AddCommand(alpha)
|
cmds.AddCommand(alpha)
|
||||||
cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), out, err))
|
cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), ioStreams))
|
||||||
cmds.AddCommand(NewCmdPlugin(f, in, out, err))
|
cmds.AddCommand(NewCmdPlugin(f, in, out, err))
|
||||||
cmds.AddCommand(NewCmdVersion(f, ioStreams))
|
cmds.AddCommand(NewCmdVersion(f, ioStreams))
|
||||||
cmds.AddCommand(NewCmdApiVersions(f, ioStreams))
|
cmds.AddCommand(NewCmdApiVersions(f, ioStreams))
|
||||||
|
@ -14,6 +14,7 @@ go_library(
|
|||||||
"current_context.go",
|
"current_context.go",
|
||||||
"delete_cluster.go",
|
"delete_cluster.go",
|
||||||
"delete_context.go",
|
"delete_context.go",
|
||||||
|
"flags.go",
|
||||||
"get_clusters.go",
|
"get_clusters.go",
|
||||||
"get_contexts.go",
|
"get_contexts.go",
|
||||||
"navigation_step_parser.go",
|
"navigation_step_parser.go",
|
||||||
@ -30,6 +31,7 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/kubectl/cmd/templates:go_default_library",
|
"//pkg/kubectl/cmd/templates:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
"//pkg/kubectl/util/i18n:go_default_library",
|
"//pkg/kubectl/util/i18n:go_default_library",
|
||||||
"//pkg/printers:go_default_library",
|
"//pkg/printers:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
@ -64,6 +66,7 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||||
|
@ -18,7 +18,6 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
@ -27,11 +26,12 @@ import (
|
|||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCmdConfig creates a command object for the "config" action, and adds all child commands to it.
|
// NewCmdConfig creates a command object for the "config" action, and adds all child commands to it.
|
||||||
func NewCmdConfig(f cmdutil.Factory, pathOptions *clientcmd.PathOptions, out, errOut io.Writer) *cobra.Command {
|
func NewCmdConfig(f cmdutil.Factory, pathOptions *clientcmd.PathOptions, streams genericclioptions.IOStreams) *cobra.Command {
|
||||||
if len(pathOptions.ExplicitFileFlag) == 0 {
|
if len(pathOptions.ExplicitFileFlag) == 0 {
|
||||||
pathOptions.ExplicitFileFlag = clientcmd.RecommendedConfigPathFlag
|
pathOptions.ExplicitFileFlag = clientcmd.RecommendedConfigPathFlag
|
||||||
}
|
}
|
||||||
@ -48,25 +48,26 @@ func NewCmdConfig(f cmdutil.Factory, pathOptions *clientcmd.PathOptions, out, er
|
|||||||
1. If the --` + pathOptions.ExplicitFileFlag + ` flag is set, then only that file is loaded. The flag may only be set once and no merging takes place.
|
1. If the --` + pathOptions.ExplicitFileFlag + ` flag is set, then only that file is loaded. The flag may only be set once and no merging takes place.
|
||||||
2. If $` + pathOptions.EnvVar + ` environment variable is set, then it is used a list of paths (normal path delimitting rules for your system). These paths are merged. When a value is modified, it is modified in the file that defines the stanza. When a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the last file in the list.
|
2. If $` + pathOptions.EnvVar + ` environment variable is set, then it is used a list of paths (normal path delimitting rules for your system). These paths are merged. When a value is modified, it is modified in the file that defines the stanza. When a value is created, it is created in the first file that exists. If no files in the chain exist, then it creates the last file in the list.
|
||||||
3. Otherwise, ` + path.Join("${HOME}", pathOptions.GlobalFileSubpath) + ` is used and no merging takes place.`),
|
3. Otherwise, ` + path.Join("${HOME}", pathOptions.GlobalFileSubpath) + ` is used and no merging takes place.`),
|
||||||
Run: cmdutil.DefaultSubCommandRun(errOut),
|
Run: cmdutil.DefaultSubCommandRun(streams.Out),
|
||||||
}
|
}
|
||||||
|
|
||||||
// file paths are common to all sub commands
|
// file paths are common to all sub commands
|
||||||
cmd.PersistentFlags().StringVar(&pathOptions.LoadingRules.ExplicitPath, pathOptions.ExplicitFileFlag, pathOptions.LoadingRules.ExplicitPath, "use a particular kubeconfig file")
|
cmd.PersistentFlags().StringVar(&pathOptions.LoadingRules.ExplicitPath, pathOptions.ExplicitFileFlag, pathOptions.LoadingRules.ExplicitPath, "use a particular kubeconfig file")
|
||||||
|
|
||||||
cmd.AddCommand(NewCmdConfigView(f, out, errOut, pathOptions))
|
// TODO(juanvallejo): update all subcommands to work with genericclioptions.IOStreams
|
||||||
cmd.AddCommand(NewCmdConfigSetCluster(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigView(f, streams, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigSetAuthInfo(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigSetCluster(streams.Out, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigSetContext(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigSetAuthInfo(streams.Out, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigSet(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigSetContext(streams.Out, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigUnset(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigSet(streams.Out, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigCurrentContext(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigUnset(streams.Out, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigUseContext(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigCurrentContext(streams.Out, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigGetContexts(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigUseContext(streams.Out, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigGetClusters(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigGetContexts(streams, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigDeleteCluster(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigGetClusters(streams.Out, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigDeleteContext(out, errOut, pathOptions))
|
cmd.AddCommand(NewCmdConfigDeleteCluster(streams.Out, pathOptions))
|
||||||
cmd.AddCommand(NewCmdConfigRenameContext(out, pathOptions))
|
cmd.AddCommand(NewCmdConfigDeleteContext(streams.Out, streams.ErrOut, pathOptions))
|
||||||
|
cmd.AddCommand(NewCmdConfigRenameContext(streams.Out, pathOptions))
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
@ -31,6 +30,7 @@ import (
|
|||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRedFederalCowHammerConfig() clientcmdapi.Config {
|
func newRedFederalCowHammerConfig() clientcmdapi.Config {
|
||||||
@ -863,9 +863,8 @@ func testConfigCommand(args []string, startingConfig clientcmdapi.Config, t *tes
|
|||||||
argsToUse = append(argsToUse, "--kubeconfig="+fakeKubeFile.Name())
|
argsToUse = append(argsToUse, "--kubeconfig="+fakeKubeFile.Name())
|
||||||
argsToUse = append(argsToUse, args...)
|
argsToUse = append(argsToUse, args...)
|
||||||
|
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
|
cmd := NewCmdConfig(cmdutil.NewFactory(cmdutil.NewTestConfigFlags()), clientcmd.NewDefaultPathOptions(), streams)
|
||||||
cmd := NewCmdConfig(cmdutil.NewFactory(cmdutil.NewTestConfigFlags()), clientcmd.NewDefaultPathOptions(), buf, buf)
|
|
||||||
cmd.SetArgs(argsToUse)
|
cmd.SetArgs(argsToUse)
|
||||||
cmd.Execute()
|
cmd.Execute()
|
||||||
|
|
||||||
|
95
pkg/kubectl/cmd/config/flags.go
Normal file
95
pkg/kubectl/cmd/config/flags.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
/*
|
||||||
|
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 config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PrintFlags composes common printer flag structs
|
||||||
|
// used across all config commands, and provides a method
|
||||||
|
// of retrieving a known printer based on flag values provided.
|
||||||
|
type PrintFlags struct {
|
||||||
|
JSONYamlPrintFlags *printers.JSONYamlPrintFlags
|
||||||
|
NamePrintFlags *printers.NamePrintFlags
|
||||||
|
TemplateFlags *printers.KubeTemplatePrintFlags
|
||||||
|
|
||||||
|
OutputFormat *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *PrintFlags) Complete(successTemplate string) error {
|
||||||
|
return f.NamePrintFlags.Complete(successTemplate)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *PrintFlags) ToPrinter() (printers.ResourcePrinter, error) {
|
||||||
|
outputFormat := ""
|
||||||
|
if f.OutputFormat != nil {
|
||||||
|
outputFormat = *f.OutputFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) {
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) {
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if p, err := f.TemplateFlags.ToPrinter(outputFormat); !printers.IsNoCompatiblePrinterError(err) {
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, printers.NoCompatiblePrinterError{Options: f}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *PrintFlags) AddFlags(cmd *cobra.Command) {
|
||||||
|
f.JSONYamlPrintFlags.AddFlags(cmd)
|
||||||
|
f.NamePrintFlags.AddFlags(cmd)
|
||||||
|
f.TemplateFlags.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].")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDefaultOutput sets a default output format if one is not provided through a flag value
|
||||||
|
func (f *PrintFlags) WithDefaultOutput(output string) *PrintFlags {
|
||||||
|
existingFormat := ""
|
||||||
|
if f.OutputFormat != nil {
|
||||||
|
existingFormat = *f.OutputFormat
|
||||||
|
}
|
||||||
|
if len(existingFormat) == 0 {
|
||||||
|
existingFormat = output
|
||||||
|
}
|
||||||
|
f.OutputFormat = &existingFormat
|
||||||
|
|
||||||
|
return f
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPrintFlags(operation string) *PrintFlags {
|
||||||
|
outputFormat := ""
|
||||||
|
|
||||||
|
return &PrintFlags{
|
||||||
|
OutputFormat: &outputFormat,
|
||||||
|
|
||||||
|
JSONYamlPrintFlags: printers.NewJSONYamlPrintFlags(),
|
||||||
|
NamePrintFlags: printers.NewNamePrintFlags(operation),
|
||||||
|
TemplateFlags: printers.NewKubeTemplatePrintFlags(),
|
||||||
|
}
|
||||||
|
}
|
@ -31,6 +31,7 @@ import (
|
|||||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
"k8s.io/kubernetes/pkg/printers"
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
)
|
)
|
||||||
@ -41,7 +42,8 @@ type GetContextsOptions struct {
|
|||||||
nameOnly bool
|
nameOnly bool
|
||||||
showHeaders bool
|
showHeaders bool
|
||||||
contextNames []string
|
contextNames []string
|
||||||
out io.Writer
|
|
||||||
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -57,8 +59,12 @@ var (
|
|||||||
|
|
||||||
// NewCmdConfigGetContexts creates a command object for the "get-contexts" action, which
|
// NewCmdConfigGetContexts creates a command object for the "get-contexts" action, which
|
||||||
// retrieves one or more contexts from a kubeconfig.
|
// retrieves one or more contexts from a kubeconfig.
|
||||||
func NewCmdConfigGetContexts(out io.Writer, configAccess clientcmd.ConfigAccess) *cobra.Command {
|
func NewCmdConfigGetContexts(streams genericclioptions.IOStreams, configAccess clientcmd.ConfigAccess) *cobra.Command {
|
||||||
options := &GetContextsOptions{configAccess: configAccess}
|
options := &GetContextsOptions{
|
||||||
|
configAccess: configAccess,
|
||||||
|
|
||||||
|
IOStreams: streams,
|
||||||
|
}
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "get-contexts [(-o|--output=)name)]",
|
Use: "get-contexts [(-o|--output=)name)]",
|
||||||
@ -74,22 +80,22 @@ func NewCmdConfigGetContexts(out io.Writer, configAccess clientcmd.ConfigAccess)
|
|||||||
cmdutil.CheckErr(fmt.Errorf("output must be one of '' or 'name': %v", outputFormat))
|
cmdutil.CheckErr(fmt.Errorf("output must be one of '' or 'name': %v", outputFormat))
|
||||||
}
|
}
|
||||||
if !supportedOutputTypes.Has(outputFormat) {
|
if !supportedOutputTypes.Has(outputFormat) {
|
||||||
fmt.Fprintf(out, "--output %v is not available in kubectl config get-contexts; resetting to default output format\n", outputFormat)
|
fmt.Fprintf(options.Out, "--output %v is not available in kubectl config get-contexts; resetting to default output format\n", outputFormat)
|
||||||
cmd.Flags().Set("output", "")
|
cmd.Flags().Set("output", "")
|
||||||
}
|
}
|
||||||
cmdutil.CheckErr(options.Complete(cmd, args, out))
|
cmdutil.CheckErr(options.Complete(cmd, args))
|
||||||
cmdutil.CheckErr(options.RunGetContexts())
|
cmdutil.CheckErr(options.RunGetContexts())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmdutil.AddOutputFlags(cmd)
|
|
||||||
cmdutil.AddNoHeadersFlags(cmd)
|
cmd.Flags().Bool("no-headers", false, "When using the default or custom-column output format, don't print headers (default print headers).")
|
||||||
|
cmd.Flags().StringP("output", "o", "", "Output format. One of: name")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete assigns GetContextsOptions from the args.
|
// Complete assigns GetContextsOptions from the args.
|
||||||
func (o *GetContextsOptions) Complete(cmd *cobra.Command, args []string, out io.Writer) error {
|
func (o *GetContextsOptions) Complete(cmd *cobra.Command, args []string) error {
|
||||||
o.contextNames = args
|
o.contextNames = args
|
||||||
o.out = out
|
|
||||||
o.nameOnly = false
|
o.nameOnly = false
|
||||||
if cmdutil.GetFlagString(cmd, "output") == "name" {
|
if cmdutil.GetFlagString(cmd, "output") == "name" {
|
||||||
o.nameOnly = true
|
o.nameOnly = true
|
||||||
@ -109,9 +115,9 @@ func (o GetContextsOptions) RunGetContexts() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
out, found := o.out.(*tabwriter.Writer)
|
out, found := o.Out.(*tabwriter.Writer)
|
||||||
if !found {
|
if !found {
|
||||||
out = printers.GetNewTabWriter(o.out)
|
out = printers.GetNewTabWriter(o.Out)
|
||||||
defer out.Flush()
|
defer out.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,13 +17,13 @@ limitations under the License.
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
type getContextsTest struct {
|
type getContextsTest struct {
|
||||||
@ -157,11 +157,11 @@ func (test getContextsTest) run(t *testing.T) {
|
|||||||
pathOptions := clientcmd.NewDefaultPathOptions()
|
pathOptions := clientcmd.NewDefaultPathOptions()
|
||||||
pathOptions.GlobalFile = fakeKubeFile.Name()
|
pathOptions.GlobalFile = fakeKubeFile.Name()
|
||||||
pathOptions.EnvVar = ""
|
pathOptions.EnvVar = ""
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
options := GetContextsOptions{
|
options := GetContextsOptions{
|
||||||
configAccess: pathOptions,
|
configAccess: pathOptions,
|
||||||
}
|
}
|
||||||
cmd := NewCmdConfigGetContexts(buf, options.configAccess)
|
cmd := NewCmdConfigGetContexts(streams, options.configAccess)
|
||||||
if test.nameOnly {
|
if test.nameOnly {
|
||||||
cmd.Flags().Set("output", "name")
|
cmd.Flags().Set("output", "name")
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,6 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
@ -29,16 +27,24 @@ import (
|
|||||||
"k8s.io/client-go/tools/clientcmd/api/latest"
|
"k8s.io/client-go/tools/clientcmd/api/latest"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||||
"k8s.io/kubernetes/pkg/printers"
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ViewOptions struct {
|
type ViewOptions struct {
|
||||||
|
PrintFlags *PrintFlags
|
||||||
|
PrintObject printers.ResourcePrinterFunc
|
||||||
|
|
||||||
ConfigAccess clientcmd.ConfigAccess
|
ConfigAccess clientcmd.ConfigAccess
|
||||||
Merge flag.Tristate
|
Merge flag.Tristate
|
||||||
Flatten bool
|
Flatten bool
|
||||||
Minify bool
|
Minify bool
|
||||||
RawByteData bool
|
RawByteData bool
|
||||||
|
|
||||||
|
OutputFormat string
|
||||||
|
|
||||||
|
genericclioptions.IOStreams
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -56,12 +62,17 @@ var (
|
|||||||
|
|
||||||
# Get the password for the e2e user
|
# Get the password for the e2e user
|
||||||
kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'`)
|
kubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'`)
|
||||||
|
|
||||||
|
defaultOutputFormat = "yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewCmdConfigView(f cmdutil.Factory, out, errOut io.Writer, ConfigAccess clientcmd.ConfigAccess) *cobra.Command {
|
func NewCmdConfigView(f cmdutil.Factory, streams genericclioptions.IOStreams, ConfigAccess clientcmd.ConfigAccess) *cobra.Command {
|
||||||
options := &ViewOptions{ConfigAccess: ConfigAccess}
|
o := &ViewOptions{
|
||||||
// Default to yaml
|
PrintFlags: NewPrintFlags("").WithDefaultOutput("yaml"),
|
||||||
defaultOutputFormat := "yaml"
|
ConfigAccess: ConfigAccess,
|
||||||
|
|
||||||
|
IOStreams: streams,
|
||||||
|
}
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "view",
|
Use: "view",
|
||||||
@ -69,40 +80,48 @@ func NewCmdConfigView(f cmdutil.Factory, out, errOut io.Writer, ConfigAccess cli
|
|||||||
Long: view_long,
|
Long: view_long,
|
||||||
Example: view_example,
|
Example: view_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
options.Complete()
|
cmdutil.CheckErr(o.Complete(cmd))
|
||||||
outputFormat := cmdutil.GetFlagString(cmd, "output")
|
cmdutil.CheckErr(o.Validate())
|
||||||
if outputFormat == "wide" {
|
cmdutil.CheckErr(o.Run())
|
||||||
fmt.Fprintf(errOut, "--output wide is not available in kubectl config view; reset to default output format (%s)\n\n", defaultOutputFormat)
|
|
||||||
// TODO: once printing is abstracted, this should be handled at flag declaration time
|
|
||||||
cmd.Flags().Set("output", defaultOutputFormat)
|
|
||||||
}
|
|
||||||
if outputFormat == "" {
|
|
||||||
fmt.Fprintf(errOut, "Reset to default output format (%s) as --output is empty\n", defaultOutputFormat)
|
|
||||||
// TODO: once printing is abstracted, this should be handled at flag declaration time
|
|
||||||
cmd.Flags().Set("output", defaultOutputFormat)
|
|
||||||
}
|
|
||||||
|
|
||||||
printOpts := cmdutil.ExtractCmdPrintOptions(cmd, false)
|
|
||||||
printer, err := cmdutil.PrinterForOptions(printOpts)
|
|
||||||
cmdutil.CheckErr(err)
|
|
||||||
|
|
||||||
cmdutil.CheckErr(options.Run(out, printer))
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdutil.AddPrinterFlags(cmd)
|
o.PrintFlags.AddFlags(cmd)
|
||||||
cmd.Flags().Set("output", defaultOutputFormat)
|
|
||||||
|
|
||||||
options.Merge.Default(true)
|
o.Merge.Default(true)
|
||||||
mergeFlag := cmd.Flags().VarPF(&options.Merge, "merge", "", "Merge the full hierarchy of kubeconfig files")
|
mergeFlag := cmd.Flags().VarPF(&o.Merge, "merge", "", "Merge the full hierarchy of kubeconfig files")
|
||||||
mergeFlag.NoOptDefVal = "true"
|
mergeFlag.NoOptDefVal = "true"
|
||||||
cmd.Flags().BoolVar(&options.RawByteData, "raw", options.RawByteData, "Display raw byte data")
|
cmd.Flags().BoolVar(&o.RawByteData, "raw", o.RawByteData, "Display raw byte data")
|
||||||
cmd.Flags().BoolVar(&options.Flatten, "flatten", options.Flatten, "Flatten the resulting kubeconfig file into self-contained output (useful for creating portable kubeconfig files)")
|
cmd.Flags().BoolVar(&o.Flatten, "flatten", o.Flatten, "Flatten the resulting kubeconfig file into self-contained output (useful for creating portable kubeconfig files)")
|
||||||
cmd.Flags().BoolVar(&options.Minify, "minify", options.Minify, "Remove all information not used by current-context from the output")
|
cmd.Flags().BoolVar(&o.Minify, "minify", o.Minify, "Remove all information not used by current-context from the output")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o ViewOptions) Run(out io.Writer, printer printers.ResourcePrinter) error {
|
func (o *ViewOptions) Complete(cmd *cobra.Command) error {
|
||||||
|
if o.ConfigAccess.IsExplicitFile() {
|
||||||
|
if !o.Merge.Provided() {
|
||||||
|
o.Merge.Set("false")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printer, err := o.PrintFlags.ToPrinter()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.PrintObject = printer.PrintObj
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o ViewOptions) Validate() error {
|
||||||
|
if !o.Merge.Value() && !o.ConfigAccess.IsExplicitFile() {
|
||||||
|
return errors.New("if merge==false a precise file must to specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o ViewOptions) Run() error {
|
||||||
config, err := o.loadConfig()
|
config, err := o.loadConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -127,22 +146,7 @@ func (o ViewOptions) Run(out io.Writer, printer printers.ResourcePrinter) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = printer.PrintObj(convertedObj, out)
|
return o.PrintObject(convertedObj, o.Out)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *ViewOptions) Complete() bool {
|
|
||||||
if o.ConfigAccess.IsExplicitFile() {
|
|
||||||
if !o.Merge.Provided() {
|
|
||||||
o.Merge.Set("false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o ViewOptions) loadConfig() (*clientcmdapi.Config, error) {
|
func (o ViewOptions) loadConfig() (*clientcmdapi.Config, error) {
|
||||||
@ -155,14 +159,6 @@ func (o ViewOptions) loadConfig() (*clientcmdapi.Config, error) {
|
|||||||
return config, err
|
return config, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o ViewOptions) Validate() error {
|
|
||||||
if !o.Merge.Value() && !o.ConfigAccess.IsExplicitFile() {
|
|
||||||
return errors.New("if merge==false a precise file must to specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getStartingConfig returns the Config object built from the sources specified by the options, the filename read (only if it was a single file), and an error if something goes wrong
|
// getStartingConfig returns the Config object built from the sources specified by the options, the filename read (only if it was a single file), and an error if something goes wrong
|
||||||
func (o *ViewOptions) getStartingConfig() (*clientcmdapi.Config, error) {
|
func (o *ViewOptions) getStartingConfig() (*clientcmdapi.Config, error) {
|
||||||
switch {
|
switch {
|
||||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
@ -25,6 +24,7 @@ import (
|
|||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
type viewClusterTest struct {
|
type viewClusterTest struct {
|
||||||
@ -141,9 +141,8 @@ func (test viewClusterTest) run(t *testing.T) {
|
|||||||
pathOptions := clientcmd.NewDefaultPathOptions()
|
pathOptions := clientcmd.NewDefaultPathOptions()
|
||||||
pathOptions.GlobalFile = fakeKubeFile.Name()
|
pathOptions.GlobalFile = fakeKubeFile.Name()
|
||||||
pathOptions.EnvVar = ""
|
pathOptions.EnvVar = ""
|
||||||
buf := bytes.NewBuffer([]byte{})
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
errBuf := bytes.NewBuffer([]byte{})
|
cmd := NewCmdConfigView(cmdutil.NewFactory(cmdutil.NewTestConfigFlags()), streams, pathOptions)
|
||||||
cmd := NewCmdConfigView(cmdutil.NewFactory(cmdutil.NewTestConfigFlags()), buf, errBuf, pathOptions)
|
|
||||||
cmd.Flags().Parse(test.flags)
|
cmd.Flags().Parse(test.flags)
|
||||||
if err := cmd.Execute(); err != nil {
|
if err := cmd.Execute(); err != nil {
|
||||||
t.Fatalf("unexpected error executing command: %v,kubectl config view flags: %v", err, test.flags)
|
t.Fatalf("unexpected error executing command: %v,kubectl config view flags: %v", err, test.flags)
|
||||||
|
@ -124,8 +124,6 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||||||
Example: delete_example,
|
Example: delete_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
options := deleteFlags.ToOptions(out, errOut)
|
options := deleteFlags.ToOptions(out, errOut)
|
||||||
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
|
|
||||||
|
|
||||||
if err := options.Complete(f, out, errOut, args, cmd); err != nil {
|
if err := options.Complete(f, out, errOut, args, cmd); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
@ -185,6 +183,11 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *DeleteOptions) Validate(cmd *cobra.Command) error {
|
func (o *DeleteOptions) Validate(cmd *cobra.Command) error {
|
||||||
|
outputMode := cmdutil.GetFlagString(cmd, "output")
|
||||||
|
if outputMode != "" && outputMode != "name" {
|
||||||
|
return cmdutil.UsageErrorf(cmd, "Unexpected -o output mode: %v. We only support '-o name'.", outputMode)
|
||||||
|
}
|
||||||
|
|
||||||
if o.DeleteAll && len(o.LabelSelector) > 0 {
|
if o.DeleteAll && len(o.LabelSelector) > 0 {
|
||||||
return fmt.Errorf("cannot set --all and --selector at the same time")
|
return fmt.Errorf("cannot set --all and --selector at the same time")
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,7 @@ func fakecmd() *cobra.Command {
|
|||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])",
|
Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])",
|
||||||
DisableFlagsInUseLine: true,
|
DisableFlagsInUseLine: true,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {},
|
||||||
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@ -91,8 +91,15 @@ type ReplaceOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewReplaceOptions(out, errOut io.Writer) *ReplaceOptions {
|
func NewReplaceOptions(out, errOut io.Writer) *ReplaceOptions {
|
||||||
|
outputFormat := ""
|
||||||
|
|
||||||
return &ReplaceOptions{
|
return &ReplaceOptions{
|
||||||
PrintFlags: printers.NewPrintFlags("replaced"),
|
// TODO(juanvallejo): figure out why we only support the "name" outputFormat in this command
|
||||||
|
// we only support "-o name" for this command, so only register the name printer
|
||||||
|
PrintFlags: &printers.PrintFlags{
|
||||||
|
OutputFormat: &outputFormat,
|
||||||
|
NamePrintFlags: printers.NewNamePrintFlags("replaced"),
|
||||||
|
},
|
||||||
DeleteFlags: NewDeleteFlags("to use to replace the resource."),
|
DeleteFlags: NewDeleteFlags("to use to replace the resource."),
|
||||||
|
|
||||||
Out: out,
|
Out: out,
|
||||||
@ -110,7 +117,6 @@ func NewCmdReplace(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||||||
Long: replaceLong,
|
Long: replaceLong,
|
||||||
Example: replaceExample,
|
Example: replaceExample,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
|
|
||||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||||
cmdutil.CheckErr(o.Validate(cmd))
|
cmdutil.CheckErr(o.Validate(cmd))
|
||||||
cmdutil.CheckErr(o.Run())
|
cmdutil.CheckErr(o.Run())
|
||||||
|
@ -93,9 +93,16 @@ type ScaleOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewScaleOptions(ioStreams genericclioptions.IOStreams) *ScaleOptions {
|
func NewScaleOptions(ioStreams genericclioptions.IOStreams) *ScaleOptions {
|
||||||
|
outputFormat := ""
|
||||||
|
|
||||||
return &ScaleOptions{
|
return &ScaleOptions{
|
||||||
|
// TODO(juanvallejo): figure out why we only support the "name" outputFormat in this command
|
||||||
|
// we only support "-o name" for this command, so only register the name printer
|
||||||
|
PrintFlags: &printers.PrintFlags{
|
||||||
|
OutputFormat: &outputFormat,
|
||||||
|
NamePrintFlags: printers.NewNamePrintFlags("scaled"),
|
||||||
|
},
|
||||||
RecordFlags: genericclioptions.NewRecordFlags(),
|
RecordFlags: genericclioptions.NewRecordFlags(),
|
||||||
PrintFlags: printers.NewPrintFlags("scaled"),
|
|
||||||
CurrentReplicas: -1,
|
CurrentReplicas: -1,
|
||||||
Recorder: genericclioptions.NoopRecorder{},
|
Recorder: genericclioptions.NoopRecorder{},
|
||||||
IOStreams: ioStreams,
|
IOStreams: ioStreams,
|
||||||
@ -173,9 +180,6 @@ func (o *ScaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *ScaleOptions) Validate(cmd *cobra.Command) error {
|
func (o *ScaleOptions) Validate(cmd *cobra.Command) error {
|
||||||
if err := cmdutil.ValidateOutputArgs(cmd); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if o.Replicas < 0 {
|
if o.Replicas < 0 {
|
||||||
return fmt.Errorf("The --replicas=COUNT flag is required, and COUNT must be greater than or equal to 0")
|
return fmt.Errorf("The --replicas=COUNT flag is required, and COUNT must be greater than or equal to 0")
|
||||||
}
|
}
|
||||||
|
@ -18,222 +18,12 @@ package util
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
kubectlscheme "k8s.io/kubernetes/pkg/kubectl/scheme"
|
|
||||||
"k8s.io/kubernetes/pkg/printers"
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
|
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddPrinterFlags adds printing related flags to a command (e.g. output format, no headers, template path)
|
|
||||||
func AddPrinterFlags(cmd *cobra.Command) {
|
|
||||||
AddNonDeprecatedPrinterFlags(cmd)
|
|
||||||
|
|
||||||
cmd.Flags().String("output-version", "", "DEPRECATED: To use a specific API version, fully-qualify the resource, version, and group (for example: 'jobs.v1.batch/myjob').")
|
|
||||||
cmd.Flags().MarkDeprecated("output-version", "The resource is used exactly as fetched from the API. To get a specific API version, fully-qualify the resource, version, and group (for example: 'jobs.v1.batch/myjob').")
|
|
||||||
cmd.Flags().MarkHidden("output-version")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddNonDeprecatedPrinterFlags supports the conversion case which must logically have output-version. Once output-version
|
|
||||||
// is completely removed, this function can go away.
|
|
||||||
func AddNonDeprecatedPrinterFlags(cmd *cobra.Command) {
|
|
||||||
AddOutputFlags(cmd)
|
|
||||||
AddNoHeadersFlags(cmd)
|
|
||||||
cmd.Flags().Bool("show-labels", false, "When printing, show all labels as the last column (default hide labels column)")
|
|
||||||
cmd.Flags().String("template", "", "Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].")
|
|
||||||
cmd.MarkFlagFilename("template")
|
|
||||||
cmd.Flags().String("sort-by", "", "If non-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. '{.metadata.name}'). The field in the API resource specified by this JSONPath expression must be an integer or a string.")
|
|
||||||
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")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddOutputFlagsForMutation adds output related flags to a command. Used by mutations only.
|
|
||||||
func AddOutputFlagsForMutation(cmd *cobra.Command) {
|
|
||||||
cmd.Flags().StringP("output", "o", "", "Output mode. Use \"-o name\" for shorter output (resource/name).")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddOutputVarFlagsForMutation adds output related flags to a command. Used by mutations only.
|
|
||||||
func AddOutputVarFlagsForMutation(cmd *cobra.Command, output *string) {
|
|
||||||
cmd.Flags().StringVarP(output, "output", "o", *output, "Output mode. Use \"-o name\" for shorter output (resource/name).")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddOutputFlags adds output related flags to a command.
|
|
||||||
func AddOutputFlags(cmd *cobra.Command) {
|
|
||||||
cmd.Flags().StringP("output", "o", "", "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].")
|
|
||||||
cmd.Flags().Bool("allow-missing-template-keys", true, "If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddNoHeadersFlags adds no-headers flags to a command.
|
|
||||||
func AddNoHeadersFlags(cmd *cobra.Command) {
|
|
||||||
cmd.Flags().Bool("no-headers", false, "When using the default or custom-column output format, don't print headers (default print headers).")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidateOutputArgs validates -o flag args for mutations
|
|
||||||
func ValidateOutputArgs(cmd *cobra.Command) error {
|
|
||||||
outputMode := GetFlagString(cmd, "output")
|
|
||||||
if outputMode != "" && outputMode != "name" {
|
|
||||||
return UsageErrorf(cmd, "Unexpected -o output mode: %v. We only support '-o name'.", outputMode)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrintSuccess prints a success message and can do a "-o name" as "shortOutput"
|
|
||||||
// TODO this should really just be a printer. It's got just about the exact same signature.
|
|
||||||
func PrintSuccess(shortOutput bool, out io.Writer, obj runtime.Object, dryRun bool, operation string) {
|
|
||||||
dryRunMsg := ""
|
|
||||||
if dryRun {
|
|
||||||
dryRunMsg = " (dry run)"
|
|
||||||
}
|
|
||||||
|
|
||||||
// match name printer format
|
|
||||||
name := "<unknown>"
|
|
||||||
if acc, err := meta.Accessor(obj); err == nil {
|
|
||||||
if n := acc.GetName(); len(n) > 0 {
|
|
||||||
name = n
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// legacy scheme to be sure we work ok with internal types.
|
|
||||||
// TODO internal types aren't supposed to exist here
|
|
||||||
groupKind := printers.GetObjectGroupKind(obj, legacyscheme.Scheme)
|
|
||||||
kindString := fmt.Sprintf("%s.%s", strings.ToLower(groupKind.Kind), groupKind.Group)
|
|
||||||
if len(groupKind.Group) == 0 {
|
|
||||||
kindString = strings.ToLower(groupKind.Kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
if shortOutput {
|
|
||||||
// -o name: prints resource/name
|
|
||||||
fmt.Fprintf(out, "%s/%s\n", kindString, name)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// understandable output by default
|
|
||||||
fmt.Fprintf(out, "%s \"%s\" %s%s\n", kindString, name, operation, dryRunMsg)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrintObject prints a single object based on the default command options
|
|
||||||
// TODO this should go away once commands can embed the PrintOptions instead
|
|
||||||
func PrintObject(cmd *cobra.Command, obj runtime.Object, out io.Writer) error {
|
|
||||||
printer, err := PrinterForOptions(ExtractCmdPrintOptions(cmd, false))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return printer.PrintObj(obj, out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PrinterForOptions returns the printer for the outputOptions (if given) or
|
|
||||||
// returns the default printer for the command.
|
|
||||||
// TODO this should become a function on the PrintOptions struct
|
|
||||||
func PrinterForOptions(options *printers.PrintOptions) (printers.ResourcePrinter, error) {
|
|
||||||
// TODO: used by the custom column implementation and the name implementation, break this dependency
|
|
||||||
decoders := []runtime.Decoder{kubectlscheme.Codecs.UniversalDecoder(), unstructured.UnstructuredJSONScheme}
|
|
||||||
encoder := kubectlscheme.Codecs.LegacyCodec(kubectlscheme.Registry.RegisteredGroupVersions()...)
|
|
||||||
|
|
||||||
printer, err := printers.GetStandardPrinter(kubectlscheme.Scheme, encoder, decoders, *options)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// we try to convert to HumanReadablePrinter, if return ok, it must be no generic
|
|
||||||
// we execute AddHandlers() here before maybeWrapSortingPrinter so that we don't
|
|
||||||
// need to convert to delegatePrinter again then invoke AddHandlers()
|
|
||||||
// TODO this looks highly questionable. human readable printers are baked into code. This can just live in the definition of the handler itself
|
|
||||||
// TODO or be registered there
|
|
||||||
if humanReadablePrinter, ok := printer.(printers.PrintHandler); ok {
|
|
||||||
printersinternal.AddHandlers(humanReadablePrinter)
|
|
||||||
}
|
|
||||||
|
|
||||||
printer = maybeWrapSortingPrinter(printer, *options)
|
|
||||||
|
|
||||||
// wrap the printer in a versioning printer that understands when to convert and when not to convert
|
|
||||||
printer = printers.NewVersionedPrinter(printer, legacyscheme.Scheme, legacyscheme.Scheme, kubectlscheme.Versions...)
|
|
||||||
|
|
||||||
return printer, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ExtractCmdPrintOptions parses printer specific commandline args and
|
|
||||||
// returns a PrintOptions object.
|
|
||||||
// Requires that printer flags have been added to cmd (see AddPrinterFlags)
|
|
||||||
func ExtractCmdPrintOptions(cmd *cobra.Command, withNamespace bool) *printers.PrintOptions {
|
|
||||||
flags := cmd.Flags()
|
|
||||||
|
|
||||||
columnLabel, err := flags.GetStringSlice("label-columns")
|
|
||||||
if err != nil {
|
|
||||||
columnLabel = []string{}
|
|
||||||
}
|
|
||||||
|
|
||||||
options := &printers.PrintOptions{
|
|
||||||
NoHeaders: GetFlagBool(cmd, "no-headers"),
|
|
||||||
Wide: GetWideFlag(cmd),
|
|
||||||
ShowAll: GetFlagBool(cmd, "show-all"),
|
|
||||||
ShowLabels: GetFlagBool(cmd, "show-labels"),
|
|
||||||
AbsoluteTimestamps: isWatch(cmd),
|
|
||||||
ColumnLabels: columnLabel,
|
|
||||||
WithNamespace: withNamespace,
|
|
||||||
}
|
|
||||||
|
|
||||||
var outputFormat string
|
|
||||||
if flags.Lookup("output") != nil {
|
|
||||||
outputFormat = GetFlagString(cmd, "output")
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.Lookup("sort-by") != nil {
|
|
||||||
options.SortBy = GetFlagString(cmd, "sort-by")
|
|
||||||
}
|
|
||||||
|
|
||||||
// templates are logically optional for specifying a format.
|
|
||||||
// TODO once https://github.com/kubernetes/kubernetes/issues/12668 is fixed, this should fall back to GetFlagString
|
|
||||||
var templateFile string
|
|
||||||
if flag := flags.Lookup("template"); flag != nil {
|
|
||||||
if flag.Value.Type() == "string" {
|
|
||||||
templateFile = GetFlagString(cmd, "template")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(outputFormat) == 0 && len(templateFile) != 0 {
|
|
||||||
outputFormat = "template"
|
|
||||||
}
|
|
||||||
|
|
||||||
templateFormats := []string{
|
|
||||||
"go-template=", "go-template-file=", "jsonpath=", "jsonpath-file=", "custom-columns=", "custom-columns-file=",
|
|
||||||
}
|
|
||||||
for _, format := range templateFormats {
|
|
||||||
if strings.HasPrefix(outputFormat, format) {
|
|
||||||
templateFile = outputFormat[len(format):]
|
|
||||||
outputFormat = format[:len(format)-1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this function may be invoked by a command that did not call AddPrinterFlags first, so we need
|
|
||||||
// to be safe about how we access the allow-missing-template-keys flag
|
|
||||||
if flags.Lookup("allow-missing-template-keys") != nil {
|
|
||||||
options.AllowMissingKeys = GetFlagBool(cmd, "allow-missing-template-keys")
|
|
||||||
}
|
|
||||||
|
|
||||||
options.OutputFormatType = outputFormat
|
|
||||||
options.OutputFormatArgument = templateFile
|
|
||||||
|
|
||||||
return options
|
|
||||||
}
|
|
||||||
|
|
||||||
func maybeWrapSortingPrinter(printer printers.ResourcePrinter, printOpts printers.PrintOptions) printers.ResourcePrinter {
|
|
||||||
if len(printOpts.SortBy) != 0 {
|
|
||||||
return &kubectl.SortingPrinter{
|
|
||||||
Delegate: printer,
|
|
||||||
SortField: fmt.Sprintf("{%s}", printOpts.SortBy),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return printer
|
|
||||||
}
|
|
||||||
|
|
||||||
// SuggestApiResources returns a suggestion to use the "api-resources" command
|
// SuggestApiResources returns a suggestion to use the "api-resources" command
|
||||||
// to retrieve a supported list of resources
|
// to retrieve a supported list of resources
|
||||||
func SuggestApiResources(parent string) string {
|
func SuggestApiResources(parent string) string {
|
||||||
|
@ -65,13 +65,17 @@ func (f *PrintFlags) ToPrinter() (ResourcePrinter, error) {
|
|||||||
outputFormat = *f.OutputFormat
|
outputFormat = *f.OutputFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.JSONYamlPrintFlags != nil {
|
||||||
if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) {
|
if p, err := f.JSONYamlPrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) {
|
||||||
return p, err
|
return p, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.NamePrintFlags != nil {
|
||||||
if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) {
|
if p, err := f.NamePrintFlags.ToPrinter(outputFormat); !IsNoCompatiblePrinterError(err) {
|
||||||
return p, err
|
return p, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil, NoCompatiblePrinterError{Options: f, OutputFormat: f.OutputFormat}
|
return nil, NoCompatiblePrinterError{Options: f, OutputFormat: f.OutputFormat}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user