Remove cmd from kubectl/cmd/factory

This commit is contained in:
Tamer Tas 2015-03-14 12:45:18 +02:00
parent faab509a23
commit b39e31d8a3
20 changed files with 98 additions and 93 deletions

View File

@ -30,15 +30,15 @@ func (f *Factory) NewCmdApiVersions(out io.Writer) *cobra.Command {
Use: "apiversions",
Short: "Print available API versions.",
Run: func(cmd *cobra.Command, args []string) {
err := RunApiVersions(f, out, cmd)
err := RunApiVersions(f, out)
util.CheckErr(err)
},
}
return cmd
}
func RunApiVersions(f *Factory, out io.Writer, cmd *cobra.Command) error {
client, err := f.Client(cmd)
func RunApiVersions(f *Factory, out io.Writer) error {
client, err := f.Client()
if err != nil {
return err
}

View File

@ -42,14 +42,14 @@ func (f *Factory) NewCmdClusterInfo(out io.Writer) *cobra.Command {
}
func RunClusterInfo(factory *Factory, out io.Writer, cmd *cobra.Command) error {
client, err := factory.ClientConfig(cmd)
client, err := factory.ClientConfig()
if err != nil {
return err
}
fmt.Fprintf(out, "Kubernetes master is running at %v\n", client.Host)
mapper, typer := factory.Object(cmd)
cmdNamespace, err := factory.DefaultNamespace(cmd)
mapper, typer := factory.Object()
cmdNamespace, err := factory.DefaultNamespace()
if err != nil {
return err
}

View File

@ -50,26 +50,26 @@ type Factory struct {
flags *pflag.FlagSet
// Returns interfaces for dealing with arbitrary runtime.Objects.
Object func(cmd *cobra.Command) (meta.RESTMapper, runtime.ObjectTyper)
Object func() (meta.RESTMapper, runtime.ObjectTyper)
// Returns a client for accessing Kubernetes resources or an error.
Client func(cmd *cobra.Command) (*client.Client, error)
Client func() (*client.Client, error)
// Returns a client.Config for accessing the Kubernetes server.
ClientConfig func(cmd *cobra.Command) (*client.Config, error)
ClientConfig func() (*client.Config, error)
// Returns a RESTClient for working with the specified RESTMapping or an error. This is intended
// for working with arbitrary resources and is not guaranteed to point to a Kubernetes APIServer.
RESTClient func(cmd *cobra.Command, mapping *meta.RESTMapping) (resource.RESTClient, error)
RESTClient func(mapping *meta.RESTMapping) (resource.RESTClient, error)
// Returns a Describer for displaying the specified RESTMapping type or an error.
Describer func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Describer, error)
Describer func(mapping *meta.RESTMapping) (kubectl.Describer, error)
// Returns a Printer for formatting objects of the given type or an error.
Printer func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error)
Printer func(mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error)
// Returns a Resizer for changing the size of the specified RESTMapping type or an error
Resizer func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Resizer, error)
Resizer func(mapping *meta.RESTMapping) (kubectl.Resizer, error)
// Returns a Reaper for gracefully shutting down resources.
Reaper func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Reaper, error)
Reaper func(mapping *meta.RESTMapping) (kubectl.Reaper, error)
// Returns a schema that can validate objects stored on disk.
Validator func(*cobra.Command) (validation.Schema, error)
Validator func() (validation.Schema, error)
// Returns the default namespace to use in cases where no other namespace is specified
DefaultNamespace func(cmd *cobra.Command) (string, error)
DefaultNamespace func() (string, error)
}
// NewFactory creates a factory with the default Kubernetes resources defined
@ -94,27 +94,27 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
clients: clients,
flags: flags,
Object: func(cmd *cobra.Command) (meta.RESTMapper, runtime.ObjectTyper) {
Object: func() (meta.RESTMapper, runtime.ObjectTyper) {
cfg, err := clientConfig.ClientConfig()
cmdutil.CheckErr(err)
cmdApiVersion := cfg.Version
return kubectl.OutputVersionMapper{mapper, cmdApiVersion}, api.Scheme
},
Client: func(cmd *cobra.Command) (*client.Client, error) {
Client: func() (*client.Client, error) {
return clients.ClientForVersion("")
},
ClientConfig: func(cmd *cobra.Command) (*client.Config, error) {
ClientConfig: func() (*client.Config, error) {
return clients.ClientConfigForVersion("")
},
RESTClient: func(cmd *cobra.Command, mapping *meta.RESTMapping) (resource.RESTClient, error) {
RESTClient: func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
client, err := clients.ClientForVersion(mapping.APIVersion)
if err != nil {
return nil, err
}
return client.RESTClient, nil
},
Describer: func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Describer, error) {
Describer: func(mapping *meta.RESTMapping) (kubectl.Describer, error) {
client, err := clients.ClientForVersion(mapping.APIVersion)
if err != nil {
return nil, err
@ -125,25 +125,25 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
}
return describer, nil
},
Printer: func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) {
Printer: func(mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) {
return kubectl.NewHumanReadablePrinter(noHeaders), nil
},
Resizer: func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Resizer, error) {
Resizer: func(mapping *meta.RESTMapping) (kubectl.Resizer, error) {
client, err := clients.ClientForVersion(mapping.APIVersion)
if err != nil {
return nil, err
}
return kubectl.ResizerFor(mapping.Kind, client)
},
Reaper: func(cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.Reaper, error) {
Reaper: func(mapping *meta.RESTMapping) (kubectl.Reaper, error) {
client, err := clients.ClientForVersion(mapping.APIVersion)
if err != nil {
return nil, err
}
return kubectl.ReaperFor(mapping.Kind, client)
},
Validator: func(cmd *cobra.Command) (validation.Schema, error) {
if cmdutil.GetFlagBool(cmd, "validate") {
Validator: func() (validation.Schema, error) {
if flags.Lookup("validate").Value.String() == "true" {
client, err := clients.ClientForVersion("")
if err != nil {
return nil, err
@ -152,7 +152,7 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
}
return validation.NullSchema{}, nil
},
DefaultNamespace: func(cmd *cobra.Command) (string, error) {
DefaultNamespace: func() (string, error) {
return clientConfig.Namespace()
},
}
@ -178,7 +178,14 @@ func (f *Factory) BindFlags(flags *pflag.FlagSet) {
// TODO Add a verbose flag that turns on glog logging. Probably need a way
// to do that automatically for every subcommand.
flags.BoolVar(&f.clients.matchVersion, FlagMatchBinaryVersion, false, "Require server version to match client version")
flags.Bool("validate", false, "If true, use a schema to validate the input before sending it")
// Hack for global access to validation flag.
// TODO: Refactor out after configuration flag overhaul.
if f.flags.Lookup("validate") == nil {
f.flags.Bool("validate", false, "If true, use a schema to validate the input before sending it")
}
}
// NewKubectlCommand creates the `kubectl` command and its nested children.
@ -226,7 +233,7 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`,
// PrintObject prints an api object given command line flags to modify the output format
func (f *Factory) PrintObject(cmd *cobra.Command, obj runtime.Object, out io.Writer) error {
mapper, _ := f.Object(cmd)
mapper, _ := f.Object()
_, kind, err := api.Scheme.ObjectVersionAndKind(obj)
if err != nil {
return err
@ -252,7 +259,7 @@ func (f *Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMappin
return nil, err
}
if ok {
clientConfig, err := f.ClientConfig(cmd)
clientConfig, err := f.ClientConfig()
if err != nil {
return nil, err
}
@ -267,7 +274,7 @@ func (f *Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMappin
}
printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, version)
} else {
printer, err = f.Printer(cmd, mapping, cmdutil.GetFlagBool(cmd, "no-headers"))
printer, err = f.Printer(mapping, cmdutil.GetFlagBool(cmd, "no-headers"))
if err != nil {
return nil, err
}
@ -278,7 +285,7 @@ func (f *Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMappin
// ClientMapperForCommand returns a ClientMapper for the given command and factory.
func (f *Factory) ClientMapperForCommand(cmd *cobra.Command) resource.ClientMapper {
return resource.ClientMapperFunc(func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
return f.RESTClient(cmd, mapping)
return f.RESTClient(mapping)
})
}

View File

@ -33,8 +33,6 @@ import (
. "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
"github.com/spf13/cobra"
)
type internalType struct {
@ -120,25 +118,25 @@ func NewTestFactory() (*Factory, *testFactory, runtime.Codec) {
Typer: scheme,
}
return &Factory{
Object: func(*cobra.Command) (meta.RESTMapper, runtime.ObjectTyper) {
Object: func() (meta.RESTMapper, runtime.ObjectTyper) {
return t.Mapper, t.Typer
},
RESTClient: func(*cobra.Command, *meta.RESTMapping) (resource.RESTClient, error) {
RESTClient: func(*meta.RESTMapping) (resource.RESTClient, error) {
return t.Client, t.Err
},
Describer: func(*cobra.Command, *meta.RESTMapping) (kubectl.Describer, error) {
Describer: func(*meta.RESTMapping) (kubectl.Describer, error) {
return t.Describer, t.Err
},
Printer: func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) {
Printer: func(mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) {
return t.Printer, t.Err
},
Validator: func(cmd *cobra.Command) (validation.Schema, error) {
Validator: func() (validation.Schema, error) {
return t.Validator, t.Err
},
DefaultNamespace: func(cmd *cobra.Command) (string, error) {
DefaultNamespace: func() (string, error) {
return t.Namespace, t.Err
},
ClientConfig: func(cmd *cobra.Command) (*client.Config, error) {
ClientConfig: func() (*client.Config, error) {
return t.ClientConfig, t.Err
},
}, t, codec
@ -149,25 +147,25 @@ func NewAPIFactory() (*Factory, *testFactory, runtime.Codec) {
Validator: validation.NullSchema{},
}
return &Factory{
Object: func(*cobra.Command) (meta.RESTMapper, runtime.ObjectTyper) {
Object: func() (meta.RESTMapper, runtime.ObjectTyper) {
return latest.RESTMapper, api.Scheme
},
RESTClient: func(*cobra.Command, *meta.RESTMapping) (resource.RESTClient, error) {
RESTClient: func(*meta.RESTMapping) (resource.RESTClient, error) {
return t.Client, t.Err
},
Describer: func(*cobra.Command, *meta.RESTMapping) (kubectl.Describer, error) {
Describer: func(*meta.RESTMapping) (kubectl.Describer, error) {
return t.Describer, t.Err
},
Printer: func(cmd *cobra.Command, mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) {
Printer: func(mapping *meta.RESTMapping, noHeaders bool) (kubectl.ResourcePrinter, error) {
return t.Printer, t.Err
},
Validator: func(cmd *cobra.Command) (validation.Schema, error) {
Validator: func() (validation.Schema, error) {
return t.Validator, t.Err
},
DefaultNamespace: func(cmd *cobra.Command) (string, error) {
DefaultNamespace: func() (string, error) {
return t.Namespace, t.Err
},
ClientConfig: func(cmd *cobra.Command) (*client.Config, error) {
ClientConfig: func() (*client.Config, error) {
return t.ClientConfig, t.Err
},
}, t, latest.Codec
@ -194,7 +192,7 @@ func TestClientVersions(t *testing.T) {
mapping := &meta.RESTMapping{
APIVersion: version,
}
c, err := f.RESTClient(nil, mapping)
c, err := f.RESTClient(mapping)
if err != nil {
t.Errorf("unexpected error: %v", err)
}

View File

@ -55,17 +55,17 @@ func (f *Factory) NewCmdCreate(out io.Writer) *cobra.Command {
}
func RunCreate(f *Factory, out io.Writer, cmd *cobra.Command, filenames util.StringList) error {
schema, err := f.Validator(cmd)
schema, err := f.Validator()
if err != nil {
return err
}
cmdNamespace, err := f.DefaultNamespace(cmd)
cmdNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
mapper, typer := f.Object(cmd)
mapper, typer := f.Object()
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)).
ContinueOnError().
NamespaceParam(cmdNamespace).RequireNamespace().

View File

@ -74,11 +74,11 @@ func (f *Factory) NewCmdDelete(out io.Writer) *cobra.Command {
}
func RunDelete(f *Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error {
cmdNamespace, err := f.DefaultNamespace(cmd)
cmdNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
mapper, typer := f.Object(cmd)
mapper, typer := f.Object()
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)).
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().

View File

@ -41,19 +41,19 @@ given resource.`,
}
func RunDescribe(f *Factory, out io.Writer, cmd *cobra.Command, args []string) error {
cmdNamespace, err := f.DefaultNamespace(cmd)
cmdNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
mapper, _ := f.Object(cmd)
mapper, _ := f.Object()
// TODO: use resource.Builder instead
mapping, namespace, name, err := util.ResourceFromArgs(cmd, args, mapper, cmdNamespace)
if err != nil {
return err
}
describer, err := f.Describer(cmd, mapping)
describer, err := f.Describer(mapping)
if err != nil {
return err
}

View File

@ -67,12 +67,12 @@ func RunExec(f *Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cobra.C
return util.UsageError(cmd, "COMMAND is required for exec")
}
namespace, err := f.DefaultNamespace(cmd)
namespace, err := f.DefaultNamespace()
if err != nil {
return err
}
client, err := f.Client(cmd)
client, err := f.Client()
if err != nil {
return err
}
@ -127,7 +127,7 @@ func RunExec(f *Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer, cmd *cobra.C
}
}
config, err := f.ClientConfig(cmd)
config, err := f.ClientConfig()
if err != nil {
return err
}

View File

@ -69,11 +69,11 @@ func RunExpose(f *Factory, out io.Writer, cmd *cobra.Command, args []string) err
return util.UsageError(cmd, "<name> is required for expose")
}
namespace, err := f.DefaultNamespace(cmd)
namespace, err := f.DefaultNamespace()
if err != nil {
return err
}
client, err := f.Client(cmd)
client, err := f.Client()
if err != nil {
return err
}

View File

@ -78,9 +78,9 @@ func (f *Factory) NewCmdGet(out io.Writer) *cobra.Command {
// TODO: convert all direct flag accessors to a struct and pass that instead of cmd
func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) error {
selector := util.GetFlagString(cmd, "selector")
mapper, typer := f.Object(cmd)
mapper, typer := f.Object()
cmdNamespace, err := f.DefaultNamespace(cmd)
cmdNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
@ -148,7 +148,7 @@ func RunGet(f *Factory, out io.Writer, cmd *cobra.Command, args []string) error
}
if generic {
clientConfig, err := f.ClientConfig(cmd)
clientConfig, err := f.ClientConfig()
if err != nil {
return err
}

View File

@ -159,18 +159,18 @@ func RunLabel(f *Factory, out io.Writer, cmd *cobra.Command, args []string) erro
return util.UsageError(cmd, "at least one label update is required.")
}
res := args[:2]
cmdNamespace, err := f.DefaultNamespace(cmd)
cmdNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
mapper, _ := f.Object(cmd)
mapper, _ := f.Object()
// TODO: use resource.Builder instead
mapping, namespace, name, err := util.ResourceFromArgs(cmd, res, mapper, cmdNamespace)
if err != nil {
return err
}
client, err := f.RESTClient(cmd, mapping)
client, err := f.RESTClient(mapping)
if err != nil {
return err
}

View File

@ -82,11 +82,11 @@ func RunLog(f *Factory, out io.Writer, cmd *cobra.Command, args []string) error
return util.UsageError(cmd, "log POD [CONTAINER]")
}
namespace, err := f.DefaultNamespace(cmd)
namespace, err := f.DefaultNamespace()
if err != nil {
return err
}
client, err := f.Client(cmd)
client, err := f.Client()
if err != nil {
return err
}

View File

@ -68,12 +68,12 @@ func RunPortForward(f *Factory, cmd *cobra.Command, args []string) error {
return util.UsageError(cmd, "at least 1 PORT is required for port-forward")
}
namespace, err := f.DefaultNamespace(cmd)
namespace, err := f.DefaultNamespace()
if err != nil {
return err
}
client, err := f.Client(cmd)
client, err := f.Client()
if err != nil {
return err
}
@ -87,7 +87,7 @@ func RunPortForward(f *Factory, cmd *cobra.Command, args []string) error {
glog.Fatalf("Unable to execute command because pod is not running. Current status=%v", pod.Status.Phase)
}
config, err := f.ClientConfig(cmd)
config, err := f.ClientConfig()
if err != nil {
return err
}

View File

@ -58,7 +58,7 @@ func RunProxy(f *Factory, out io.Writer, cmd *cobra.Command) error {
port := util.GetFlagInt(cmd, "port")
fmt.Fprintf(out, "Starting to serve on localhost:%d", port)
clientConfig, err := f.ClientConfig(cmd)
clientConfig, err := f.ClientConfig()
if err != nil {
return err
}

View File

@ -68,19 +68,19 @@ func RunResize(f *Factory, out io.Writer, cmd *cobra.Command, args []string) err
return util.UsageError(cmd, "--replicas=COUNT RESOURCE ID")
}
cmdNamespace, err := f.DefaultNamespace(cmd)
cmdNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
mapper, _ := f.Object(cmd)
mapper, _ := f.Object()
// TODO: use resource.Builder instead
mapping, namespace, name, err := util.ResourceFromArgs(cmd, args, mapper, cmdNamespace)
if err != nil {
return err
}
resizer, err := f.Resizer(cmd, mapping)
resizer, err := f.Resizer(mapping)
if err != nil {
return err
}

View File

@ -72,18 +72,18 @@ func RunRollingUpdate(f *Factory, out io.Writer, cmd *cobra.Command, args []stri
return util.UsageError(cmd, "Must specify the controller to update")
}
oldName := args[0]
schema, err := f.Validator(cmd)
schema, err := f.Validator()
if err != nil {
return err
}
clientConfig, err := f.ClientConfig(cmd)
clientConfig, err := f.ClientConfig()
if err != nil {
return err
}
cmdApiVersion := clientConfig.Version
mapper, typer := f.Object(cmd)
mapper, typer := f.Object()
// TODO: use resource.Builder instead
mapping, namespace, newName, data, err := util.ResourceFromFile(filename, typer, mapper, schema, cmdApiVersion)
if err != nil {
@ -97,7 +97,7 @@ func RunRollingUpdate(f *Factory, out io.Writer, cmd *cobra.Command, args []stri
filename, oldName)
}
cmdNamespace, err := f.DefaultNamespace(cmd)
cmdNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
@ -107,7 +107,7 @@ func RunRollingUpdate(f *Factory, out io.Writer, cmd *cobra.Command, args []stri
return err
}
client, err := f.Client(cmd)
client, err := f.Client()
if err != nil {
return err
}

View File

@ -69,12 +69,12 @@ func RunRunContainer(f *Factory, out io.Writer, cmd *cobra.Command, args []strin
return util.UsageError(cmd, "NAME is required for run-container")
}
namespace, err := f.DefaultNamespace(cmd)
namespace, err := f.DefaultNamespace()
if err != nil {
return err
}
client, err := f.Client(cmd)
client, err := f.Client()
if err != nil {
return err
}

View File

@ -54,9 +54,9 @@ func (f *Factory) NewCmdStop(out io.Writer) *cobra.Command {
Long: stop_long,
Example: stop_example,
Run: func(cmd *cobra.Command, args []string) {
cmdNamespace, err := f.DefaultNamespace(cmd)
cmdNamespace, err := f.DefaultNamespace()
cmdutil.CheckErr(err)
mapper, typer := f.Object(cmd)
mapper, typer := f.Object()
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)).
ContinueOnError().
NamespaceParam(cmdNamespace).RequireNamespace().
@ -69,7 +69,7 @@ func (f *Factory) NewCmdStop(out io.Writer) *cobra.Command {
cmdutil.CheckErr(r.Err())
r.Visit(func(info *resource.Info) error {
reaper, err := f.Reaper(cmd, info.Mapping)
reaper, err := f.Reaper(info.Mapping)
cmdutil.CheckErr(err)
s, err := reaper.Stop(info.Namespace, info.Name)
if err != nil {

View File

@ -58,12 +58,12 @@ func (f *Factory) NewCmdUpdate(out io.Writer) *cobra.Command {
}
func RunUpdate(f *Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error {
schema, err := f.Validator(cmd)
schema, err := f.Validator()
if err != nil {
return err
}
cmdNamespace, err := f.DefaultNamespace(cmd)
cmdNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
@ -86,7 +86,7 @@ func RunUpdate(f *Factory, out io.Writer, cmd *cobra.Command, args []string, fil
return nil
}
mapper, typer := f.Object(cmd)
mapper, typer := f.Object()
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand(cmd)).
ContinueOnError().
NamespaceParam(cmdNamespace).RequireNamespace().
@ -118,18 +118,18 @@ func RunUpdate(f *Factory, out io.Writer, cmd *cobra.Command, args []string, fil
}
func updateWithPatch(cmd *cobra.Command, args []string, f *Factory, patch string) (string, error) {
cmdNamespace, err := f.DefaultNamespace(cmd)
cmdNamespace, err := f.DefaultNamespace()
if err != nil {
return "", err
}
mapper, _ := f.Object(cmd)
mapper, _ := f.Object()
// TODO: use resource.Builder instead
mapping, namespace, name, err := cmdutil.ResourceFromArgs(cmd, args, mapper, cmdNamespace)
if err != nil {
return "", err
}
client, err := f.RESTClient(cmd, mapping)
client, err := f.RESTClient(mapping)
if err != nil {
return "", err
}

View File

@ -44,7 +44,7 @@ func RunVersion(f *Factory, out io.Writer, cmd *cobra.Command) error {
return nil
}
client, err := f.Client(cmd)
client, err := f.Client()
if err != nil {
return err
}