improve some error messages.

This commit is contained in:
Brendan Burns 2016-08-29 22:27:22 -07:00
parent 956501b1f0
commit 155fb9f4be
4 changed files with 39 additions and 13 deletions

View File

@ -48,6 +48,10 @@ var (
kubectl exec 123456-7890 -c ruby-container -i -t -- bash -il`) kubectl exec 123456-7890 -c ruby-container -i -t -- bash -il`)
) )
const (
execUsageStr = "expected 'exec <pod-name> <command> [arg1] [arg2] ... [argN]'.\n<pod-name> and <command> are required parameter for the exec command"
)
func NewCmdExec(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command { func NewCmdExec(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {
options := &ExecOptions{ options := &ExecOptions{
StreamOptions: StreamOptions{ StreamOptions: StreamOptions{
@ -135,19 +139,19 @@ type ExecOptions struct {
func (p *ExecOptions) Complete(f *cmdutil.Factory, cmd *cobra.Command, argsIn []string, argsLenAtDash int) error { func (p *ExecOptions) Complete(f *cmdutil.Factory, cmd *cobra.Command, argsIn []string, argsLenAtDash int) error {
// Let kubectl exec follow rules for `--`, see #13004 issue // Let kubectl exec follow rules for `--`, see #13004 issue
if len(p.PodName) == 0 && (len(argsIn) == 0 || argsLenAtDash == 0) { if len(p.PodName) == 0 && (len(argsIn) == 0 || argsLenAtDash == 0) {
return cmdutil.UsageError(cmd, "POD is required for exec") return cmdutil.UsageError(cmd, execUsageStr)
} }
if len(p.PodName) != 0 { if len(p.PodName) != 0 {
printDeprecationWarning("exec POD", "-p POD") printDeprecationWarning("exec <pod-name>", "-p <pod-name>")
if len(argsIn) < 1 { if len(argsIn) < 1 {
return cmdutil.UsageError(cmd, "COMMAND is required for exec") return cmdutil.UsageError(cmd, execUsageStr)
} }
p.Command = argsIn p.Command = argsIn
} else { } else {
p.PodName = argsIn[0] p.PodName = argsIn[0]
p.Command = argsIn[1:] p.Command = argsIn[1:]
if len(p.Command) < 1 { if len(p.Command) < 1 {
return cmdutil.UsageError(cmd, "COMMAND is required for exec") return cmdutil.UsageError(cmd, execUsageStr)
} }
} }

View File

@ -53,6 +53,10 @@ var (
kubectl logs --since=1h nginx`) kubectl logs --since=1h nginx`)
) )
const (
logsUsageStr = "expected 'exec <pod-name> [container-name]'.\n<pod-name> is a required parameter for the logs command"
)
type LogsOptions struct { type LogsOptions struct {
Namespace string Namespace string
ResourceArg string ResourceArg string
@ -111,17 +115,17 @@ func (o *LogsOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Com
containerName := cmdutil.GetFlagString(cmd, "container") containerName := cmdutil.GetFlagString(cmd, "container")
switch len(args) { switch len(args) {
case 0: case 0:
return cmdutil.UsageError(cmd, "POD is required for logs") return cmdutil.UsageError(cmd, logsUsageStr)
case 1: case 1:
o.ResourceArg = args[0] o.ResourceArg = args[0]
case 2: case 2:
if cmd.Flag("container").Changed { if cmd.Flag("container").Changed {
return cmdutil.UsageError(cmd, "only one of -c, [CONTAINER] arg is allowed") return cmdutil.UsageError(cmd, "only one of -c or an inline [CONTAINER] arg is allowed")
} }
o.ResourceArg = args[0] o.ResourceArg = args[0]
containerName = args[1] containerName = args[1]
default: default:
return cmdutil.UsageError(cmd, "logs POD [-c CONTAINER]") return cmdutil.UsageError(cmd, logsUsageStr)
} }
var err error var err error
o.Namespace, _, err = f.DefaultNamespace() o.Namespace, _, err = f.DefaultNamespace()

View File

@ -101,11 +101,6 @@ func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
printDeprecationWarning("scale", "resize") printDeprecationWarning("scale", "resize")
} }
count := cmdutil.GetFlagInt(cmd, "replicas")
if count < 0 {
return cmdutil.UsageError(cmd, "--replicas=COUNT is required, and COUNT must be greater than or equal to 0")
}
cmdNamespace, enforceNamespace, err := f.DefaultNamespace() cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil { if err != nil {
return err return err
@ -120,10 +115,18 @@ func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
Flatten(). Flatten().
Do() Do()
err = r.Err() err = r.Err()
if resource.IsUsageError(err) {
return cmdutil.UsageError(cmd, err.Error())
}
if err != nil { if err != nil {
return err return err
} }
count := cmdutil.GetFlagInt(cmd, "replicas")
if count < 0 {
return cmdutil.UsageError(cmd, "The --replicas=<count> flag is required, and <count> must be greater than or equal to 0")
}
infos := []*resource.Info{} infos := []*resource.Info{}
err = r.Visit(func(info *resource.Info, err error) error { err = r.Visit(func(info *resource.Info, err error) error {
if err == nil { if err == nil {

View File

@ -78,6 +78,21 @@ type Builder struct {
schema validation.Schema schema validation.Schema
} }
var missingResourceError = fmt.Errorf(`You must provide one or more resources by argument or filename.
Example resource specifications include:
'-f rsrc.yaml'
'--filename=rsrc.json'
'pods my-pod'
'services'`)
// TODO: expand this to include other errors.
func IsUsageError(err error) bool {
if err == nil {
return false
}
return err == missingResourceError
}
type resourceTuple struct { type resourceTuple struct {
Resource string Resource string
Name string Name string
@ -700,7 +715,7 @@ func (b *Builder) visitorResult() *Result {
if len(b.resources) != 0 { if len(b.resources) != 0 {
return &Result{err: fmt.Errorf("resource(s) were provided, but no name, label selector, or --all flag specified")} return &Result{err: fmt.Errorf("resource(s) were provided, but no name, label selector, or --all flag specified")}
} }
return &Result{err: fmt.Errorf("you must provide one or more resources by argument or filename (%s)", strings.Join(InputExtensions, "|"))} return &Result{err: missingResourceError}
} }
// Do returns a Result object with a Visitor for the resources identified by the Builder. // Do returns a Result object with a Visitor for the resources identified by the Builder.