diff --git a/contrib/completions/bash/kubectl b/contrib/completions/bash/kubectl index e6860231cb7..124ed7367cd 100644 --- a/contrib/completions/bash/kubectl +++ b/contrib/completions/bash/kubectl @@ -975,8 +975,17 @@ _kubectl_annotate() two_word_flags+=("-f") flags_with_completion+=("-f") flags_completion+=("__handle_filename_extension_flag json|yaml|yml") + flags+=("--no-headers") + flags+=("--output=") + two_word_flags+=("-o") + flags+=("--output-version=") flags+=("--overwrite") flags+=("--resource-version=") + flags+=("--show-all") + flags+=("-a") + flags+=("--sort-by=") + flags+=("--template=") + two_word_flags+=("-t") must_have_one_flag=() must_have_one_noun=() diff --git a/docs/man/man1/kubectl-annotate.1 b/docs/man/man1/kubectl-annotate.1 index 15396b5ae77..7568a5ba82e 100644 --- a/docs/man/man1/kubectl-annotate.1 +++ b/docs/man/man1/kubectl-annotate.1 @@ -37,6 +37,20 @@ resourcequotas (quota) or secrets. \fB\-f\fP, \fB\-\-filename\fP=[] Filename, directory, or URL to a file identifying the resource to update the annotation +.PP +\fB\-\-no\-headers\fP=false + When using the default output, don't print headers. + +.PP +\fB\-o\fP, \fB\-\-output\fP="" + Output format. One of: json|yaml|wide|name|go\-template=...|go\-template\-file=...|jsonpath=...|jsonpath\-file=... See golang template [ +\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] and jsonpath template [ +\[la]http://releases.k8s.io/HEAD/docs/user-guide/jsonpath.md\[ra]]. + +.PP +\fB\-\-output\-version\fP="" + Output the formatted object with the given version (default api\-version). + .PP \fB\-\-overwrite\fP=false If true, allow annotations to be overwritten, otherwise reject annotation updates that overwrite existing annotations. @@ -45,6 +59,19 @@ resourcequotas (quota) or secrets. \fB\-\-resource\-version\fP="" If non\-empty, the annotation update will only succeed if this is the current resource\-version for the object. Only valid when specifying a single resource. +.PP +\fB\-a\fP, \fB\-\-show\-all\fP=false + When printing, show all resources (default hide terminated pods.) + +.PP +\fB\-\-sort\-by\fP="" + If non\-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. 'ObjectMeta.Name'). The field in the API resource specified by this JSONPath expression must be an integer or a string. + +.PP +\fB\-\-template\fP="" + Template string or path to template file to use when \-o=go\-template, \-o=go\-template\-file. The template format is golang templates [ +\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]]. + .SH OPTIONS INHERITED FROM PARENT COMMANDS .PP diff --git a/docs/user-guide/kubectl/kubectl_annotate.md b/docs/user-guide/kubectl/kubectl_annotate.md index 96bf878ebc9..7d917d0db26 100644 --- a/docs/user-guide/kubectl/kubectl_annotate.md +++ b/docs/user-guide/kubectl/kubectl_annotate.md @@ -83,8 +83,14 @@ $ kubectl annotate pods foo description- ``` --all[=false]: select all resources in the namespace of the specified resource types -f, --filename=[]: Filename, directory, or URL to a file identifying the resource to update the annotation + --no-headers[=false]: When using the default output, don't print headers. + -o, --output="": Output format. One of: json|yaml|wide|name|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=... See golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [http://releases.k8s.io/HEAD/docs/user-guide/jsonpath.md]. + --output-version="": Output the formatted object with the given version (default api-version). --overwrite[=false]: If true, allow annotations to be overwritten, otherwise reject annotation updates that overwrite existing annotations. --resource-version="": If non-empty, the annotation update will only succeed if this is the current resource-version for the object. Only valid when specifying a single resource. + -a, --show-all[=false]: When printing, show all resources (default hide terminated pods.) + --sort-by="": If non-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. 'ObjectMeta.Name'). The field in the API resource specified by this JSONPath expression must be an integer or a 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]. ``` ### Options inherited from parent commands @@ -119,7 +125,7 @@ $ kubectl annotate pods foo description- * [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager -###### Auto generated by spf13/cobra at 2015-09-22 12:53:42.293299401 +0000 UTC +###### Auto generated by spf13/cobra on 14-Nov-2015 [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/user-guide/kubectl/kubectl_annotate.md?pixel)]() diff --git a/pkg/kubectl/cmd/annotate.go b/pkg/kubectl/cmd/annotate.go index e4dff167e54..51e244e5ba1 100644 --- a/pkg/kubectl/cmd/annotate.go +++ b/pkg/kubectl/cmd/annotate.go @@ -43,6 +43,10 @@ type AnnotateOptions struct { overwrite bool all bool resourceVersion string + + f *cmdutil.Factory + out io.Writer + cmd *cobra.Command } const ( @@ -87,17 +91,18 @@ func NewCmdAnnotate(f *cmdutil.Factory, out io.Writer) *cobra.Command { Long: annotate_long, Example: annotate_example, Run: func(cmd *cobra.Command, args []string) { - if err := options.Complete(f, args); err != nil { + if err := options.Complete(f, out, cmd, args); err != nil { cmdutil.CheckErr(err) } if err := options.Validate(args); err != nil { cmdutil.CheckErr(cmdutil.UsageError(cmd, err.Error())) } - if err := options.RunAnnotate(f); err != nil { + if err := options.RunAnnotate(); err != nil { cmdutil.CheckErr(err) } }, } + cmdutil.AddPrinterFlags(cmd) cmd.Flags().BoolVar(&options.overwrite, "overwrite", false, "If true, allow annotations to be overwritten, otherwise reject annotation updates that overwrite existing annotations.") cmd.Flags().BoolVar(&options.all, "all", false, "select all resources in the namespace of the specified resource types") cmd.Flags().StringVar(&options.resourceVersion, "resource-version", "", "If non-empty, the annotation update will only succeed if this is the current resource-version for the object. Only valid when specifying a single resource.") @@ -107,7 +112,8 @@ func NewCmdAnnotate(f *cmdutil.Factory, out io.Writer) *cobra.Command { } // Complete adapts from the command line args and factory to the data required. -func (o *AnnotateOptions) Complete(f *cmdutil.Factory, args []string) (err error) { +func (o *AnnotateOptions) Complete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) (err error) { + namespace, enforceNamespace, err := f.DefaultNamespace() if err != nil { return err @@ -151,6 +157,10 @@ func (o *AnnotateOptions) Complete(f *cmdutil.Factory, args []string) (err error Flatten(). Latest() + o.f = f + o.out = out + o.cmd = cmd + return nil } @@ -169,7 +179,7 @@ func (o AnnotateOptions) Validate(args []string) error { } // RunAnnotate does the work -func (o AnnotateOptions) RunAnnotate(f *cmdutil.Factory) error { +func (o AnnotateOptions) RunAnnotate() error { r := o.builder.Do() if err := r.Err(); err != nil { return err @@ -198,14 +208,23 @@ func (o AnnotateOptions) RunAnnotate(f *cmdutil.Factory) error { } mapping := info.ResourceMapping() - client, err := f.RESTClient(mapping) + client, err := o.f.RESTClient(mapping) if err != nil { return err } helper := resource.NewHelper(client, mapping) - _, err = helper.Patch(namespace, name, api.StrategicMergePatchType, patchBytes) - return err + outputObj, err := helper.Patch(namespace, name, api.StrategicMergePatchType, patchBytes) + if err != nil { + return err + } + outputFormat := cmdutil.GetFlagString(o.cmd, "output") + if outputFormat != "" { + return o.f.PrintObject(o.cmd, outputObj, o.out) + } + mapper, _ := o.f.Object() + cmdutil.PrintSuccess(mapper, false, o.out, info.Mapping.Resource, info.Name, "annotated") + return nil }) } diff --git a/pkg/kubectl/cmd/annotate_test.go b/pkg/kubectl/cmd/annotate_test.go index e7597ecc40d..fdcf2a3d08d 100644 --- a/pkg/kubectl/cmd/annotate_test.go +++ b/pkg/kubectl/cmd/annotate_test.go @@ -402,7 +402,7 @@ func TestAnnotateErrors(t *testing.T) { cmd.Flags().Set(k, v) } options := &AnnotateOptions{} - err := options.Complete(f, testCase.args) + err := options.Complete(f, buf, cmd, testCase.args) if !testCase.errFn(err) { t.Errorf("%s: unexpected error: %v", k, err) continue @@ -450,15 +450,18 @@ func TestAnnotateObject(t *testing.T) { tf.Namespace = "test" tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + buf := bytes.NewBuffer([]byte{}) + cmd := NewCmdAnnotate(f, buf) + cmd.SetOutput(buf) options := &AnnotateOptions{} args := []string{"pods/foo", "a=b", "c-"} - if err := options.Complete(f, args); err != nil { + if err := options.Complete(f, buf, cmd, args); err != nil { t.Fatalf("unexpected error: %v", err) } if err := options.Validate(args); err != nil { t.Fatalf("unexpected error: %v", err) } - if err := options.RunAnnotate(f); err != nil { + if err := options.RunAnnotate(); err != nil { t.Fatalf("unexpected error: %v", err) } } @@ -497,16 +500,19 @@ func TestAnnotateObjectFromFile(t *testing.T) { tf.Namespace = "test" tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + buf := bytes.NewBuffer([]byte{}) + cmd := NewCmdAnnotate(f, buf) + cmd.SetOutput(buf) options := &AnnotateOptions{} options.filenames = []string{"../../../examples/cassandra/cassandra.yaml"} args := []string{"a=b", "c-"} - if err := options.Complete(f, args); err != nil { + if err := options.Complete(f, buf, cmd, args); err != nil { t.Fatalf("unexpected error: %v", err) } if err := options.Validate(args); err != nil { t.Fatalf("unexpected error: %v", err) } - if err := options.RunAnnotate(f); err != nil { + if err := options.RunAnnotate(); err != nil { t.Fatalf("unexpected error: %v", err) } } @@ -547,16 +553,19 @@ func TestAnnotateMultipleObjects(t *testing.T) { tf.Namespace = "test" tf.ClientConfig = &client.Config{Version: testapi.Default.Version()} + buf := bytes.NewBuffer([]byte{}) + cmd := NewCmdAnnotate(f, buf) + cmd.SetOutput(buf) options := &AnnotateOptions{} options.all = true args := []string{"pods", "a=b", "c-"} - if err := options.Complete(f, args); err != nil { + if err := options.Complete(f, buf, cmd, args); err != nil { t.Fatalf("unexpected error: %v", err) } if err := options.Validate(args); err != nil { t.Fatalf("unexpected error: %v", err) } - if err := options.RunAnnotate(f); err != nil { + if err := options.RunAnnotate(); err != nil { t.Fatalf("unexpected error: %v", err) } }