mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 06:27:05 +00:00
Kubectl annotate command accepts a filename param
This commit is contained in:
parent
ebe50ea692
commit
7291bde309
@ -832,6 +832,12 @@ _kubectl_annotate()
|
|||||||
flags_completion=()
|
flags_completion=()
|
||||||
|
|
||||||
flags+=("--all")
|
flags+=("--all")
|
||||||
|
flags+=("--filename=")
|
||||||
|
flags_with_completion+=("--filename")
|
||||||
|
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
|
||||||
|
two_word_flags+=("-f")
|
||||||
|
flags_with_completion+=("-f")
|
||||||
|
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
|
||||||
flags+=("--help")
|
flags+=("--help")
|
||||||
flags+=("-h")
|
flags+=("-h")
|
||||||
flags+=("--no-headers")
|
flags+=("--no-headers")
|
||||||
|
@ -33,6 +33,10 @@ resourcequotas (quota) or secrets.
|
|||||||
\fB\-\-all\fP=false
|
\fB\-\-all\fP=false
|
||||||
select all resources in the namespace of the specified resource types
|
select all resources in the namespace of the specified resource types
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-f\fP, \fB\-\-filename\fP=[]
|
||||||
|
Filename, directory, or URL to a file identifying the resource to update the annotation
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-h\fP, \fB\-\-help\fP=false
|
\fB\-h\fP, \fB\-\-help\fP=false
|
||||||
help for annotate
|
help for annotate
|
||||||
@ -179,6 +183,9 @@ resourcequotas (quota) or secrets.
|
|||||||
# If the same annotation is set multiple times, only the last value will be applied
|
# If the same annotation is set multiple times, only the last value will be applied
|
||||||
$ kubectl annotate pods foo description='my frontend'
|
$ kubectl annotate pods foo description='my frontend'
|
||||||
|
|
||||||
|
# Update a pod identified by type and name in "pod.json"
|
||||||
|
$ kubectl annotate \-f pod.json description='my frontend'
|
||||||
|
|
||||||
# Update pod 'foo' with the annotation 'description' and the value 'my frontend running nginx', overwriting any existing value.
|
# Update pod 'foo' with the annotation 'description' and the value 'my frontend running nginx', overwriting any existing value.
|
||||||
$ kubectl annotate \-\-overwrite pods foo description='my frontend running nginx'
|
$ kubectl annotate \-\-overwrite pods foo description='my frontend running nginx'
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ $ kubectl describe nodes kubernetes\-minion\-emt8.c.myproject.internal
|
|||||||
# Describe a pod
|
# Describe a pod
|
||||||
$ kubectl describe pods/nginx
|
$ kubectl describe pods/nginx
|
||||||
|
|
||||||
# Describe a pod using the data in pod.json.
|
# Describe a pod identified by type and name in "pod.json"
|
||||||
$ kubectl describe \-f pod.json
|
$ kubectl describe \-f pod.json
|
||||||
|
|
||||||
# Describe all pods
|
# Describe all pods
|
||||||
|
@ -51,7 +51,7 @@ limitranges (limits), persistentvolumes (pv), persistentvolumeclaims (pvc),
|
|||||||
resourcequotas (quota) or secrets.
|
resourcequotas (quota) or secrets.
|
||||||
|
|
||||||
```
|
```
|
||||||
kubectl annotate [--overwrite] RESOURCE NAME KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
|
kubectl annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
@ -61,6 +61,9 @@ kubectl annotate [--overwrite] RESOURCE NAME KEY_1=VAL_1 ... KEY_N=VAL_N [--reso
|
|||||||
# If the same annotation is set multiple times, only the last value will be applied
|
# If the same annotation is set multiple times, only the last value will be applied
|
||||||
$ kubectl annotate pods foo description='my frontend'
|
$ kubectl annotate pods foo description='my frontend'
|
||||||
|
|
||||||
|
# Update a pod identified by type and name in "pod.json"
|
||||||
|
$ kubectl annotate -f pod.json description='my frontend'
|
||||||
|
|
||||||
# Update pod 'foo' with the annotation 'description' and the value 'my frontend running nginx', overwriting any existing value.
|
# Update pod 'foo' with the annotation 'description' and the value 'my frontend running nginx', overwriting any existing value.
|
||||||
$ kubectl annotate --overwrite pods foo description='my frontend running nginx'
|
$ kubectl annotate --overwrite pods foo description='my frontend running nginx'
|
||||||
|
|
||||||
@ -79,6 +82,7 @@ $ kubectl annotate pods foo description-
|
|||||||
|
|
||||||
```
|
```
|
||||||
--all[=false]: select all resources in the namespace of the specified resource types
|
--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
|
||||||
-h, --help[=false]: help for annotate
|
-h, --help[=false]: help for annotate
|
||||||
--no-headers[=false]: When using the default output, don't print headers.
|
--no-headers[=false]: When using the default output, don't print headers.
|
||||||
-o, --output="": Output format. One of: json|yaml|template|templatefile|wide|jsonpath.
|
-o, --output="": Output format. One of: json|yaml|template|templatefile|wide|jsonpath.
|
||||||
@ -123,7 +127,7 @@ $ kubectl annotate pods foo description-
|
|||||||
|
|
||||||
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra at 2015-08-20 22:01:12.4790376 +0000 UTC
|
###### Auto generated by spf13/cobra at 2015-08-21 07:07:55.977091863 +0000 UTC
|
||||||
|
|
||||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||||
[]()
|
[]()
|
||||||
|
@ -66,7 +66,7 @@ $ kubectl describe nodes kubernetes-minion-emt8.c.myproject.internal
|
|||||||
# Describe a pod
|
# Describe a pod
|
||||||
$ kubectl describe pods/nginx
|
$ kubectl describe pods/nginx
|
||||||
|
|
||||||
# Describe a pod using the data in pod.json.
|
# Describe a pod identified by type and name in "pod.json"
|
||||||
$ kubectl describe -f pod.json
|
$ kubectl describe -f pod.json
|
||||||
|
|
||||||
# Describe all pods
|
# Describe all pods
|
||||||
@ -121,7 +121,7 @@ $ kubectl describe pods frontend
|
|||||||
|
|
||||||
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
* [kubectl](kubectl.md) - kubectl controls the Kubernetes cluster manager
|
||||||
|
|
||||||
###### Auto generated by spf13/cobra at 2015-08-20 22:01:12.475314072 +0000 UTC
|
###### Auto generated by spf13/cobra at 2015-08-21 07:07:55.972896481 +0000 UTC
|
||||||
|
|
||||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
|
||||||
[]()
|
[]()
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
@ -36,6 +37,7 @@ type AnnotateOptions struct {
|
|||||||
newAnnotations map[string]string
|
newAnnotations map[string]string
|
||||||
removeAnnotations []string
|
removeAnnotations []string
|
||||||
builder *resource.Builder
|
builder *resource.Builder
|
||||||
|
filenames []string
|
||||||
|
|
||||||
overwrite bool
|
overwrite bool
|
||||||
all bool
|
all bool
|
||||||
@ -58,6 +60,9 @@ resourcequotas (quota) or secrets.`
|
|||||||
# If the same annotation is set multiple times, only the last value will be applied
|
# If the same annotation is set multiple times, only the last value will be applied
|
||||||
$ kubectl annotate pods foo description='my frontend'
|
$ kubectl annotate pods foo description='my frontend'
|
||||||
|
|
||||||
|
# Update a pod identified by type and name in "pod.json"
|
||||||
|
$ kubectl annotate -f pod.json description='my frontend'
|
||||||
|
|
||||||
# Update pod 'foo' with the annotation 'description' and the value 'my frontend running nginx', overwriting any existing value.
|
# Update pod 'foo' with the annotation 'description' and the value 'my frontend running nginx', overwriting any existing value.
|
||||||
$ kubectl annotate --overwrite pods foo description='my frontend running nginx'
|
$ kubectl annotate --overwrite pods foo description='my frontend running nginx'
|
||||||
|
|
||||||
@ -76,11 +81,12 @@ func NewCmdAnnotate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
options := &AnnotateOptions{}
|
options := &AnnotateOptions{}
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "annotate [--overwrite] RESOURCE NAME KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]",
|
Use: "annotate [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]",
|
||||||
Short: "Update the annotations on a resource",
|
Short: "Update the annotations on a resource",
|
||||||
Long: annotate_long,
|
Long: annotate_long,
|
||||||
Example: annotate_example,
|
Example: annotate_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
options.filenames = cmdutil.GetFlagStringSlice(cmd, "filename")
|
||||||
if err := options.Complete(f, args, out); err != nil {
|
if err := options.Complete(f, args, out); err != nil {
|
||||||
cmdutil.CheckErr(err)
|
cmdutil.CheckErr(err)
|
||||||
}
|
}
|
||||||
@ -96,12 +102,14 @@ func NewCmdAnnotate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||||||
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.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().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.")
|
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.")
|
||||||
|
usage := "Filename, directory, or URL to a file identifying the resource to update the annotation"
|
||||||
|
kubectl.AddJsonFilenameFlag(cmd, usage)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete adapts from the command line args and factory to the data required.
|
// Complete adapts from the command line args and factory to the data required.
|
||||||
func (o *AnnotateOptions) Complete(f *cmdutil.Factory, args []string, out io.Writer) (err error) {
|
func (o *AnnotateOptions) Complete(f *cmdutil.Factory, args []string, out io.Writer) (err error) {
|
||||||
namespace, _, err := f.DefaultNamespace()
|
namespace, enforceNamespace, err := f.DefaultNamespace()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -124,7 +132,7 @@ func (o *AnnotateOptions) Complete(f *cmdutil.Factory, args []string, out io.Wri
|
|||||||
return fmt.Errorf("all resources must be specified before annotation changes: %s", s)
|
return fmt.Errorf("all resources must be specified before annotation changes: %s", s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(o.resources) < 1 {
|
if len(o.resources) < 1 && len(o.filenames) == 0 {
|
||||||
return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>")
|
return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>")
|
||||||
}
|
}
|
||||||
if len(annotationArgs) < 1 {
|
if len(annotationArgs) < 1 {
|
||||||
@ -139,6 +147,7 @@ func (o *AnnotateOptions) Complete(f *cmdutil.Factory, args []string, out io.Wri
|
|||||||
o.builder = resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()).
|
o.builder = resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()).
|
||||||
ContinueOnError().
|
ContinueOnError().
|
||||||
NamespaceParam(namespace).DefaultNamespace().
|
NamespaceParam(namespace).DefaultNamespace().
|
||||||
|
FilenameParam(enforceNamespace, o.filenames...).
|
||||||
ResourceTypeOrNameArgs(o.all, o.resources...).
|
ResourceTypeOrNameArgs(o.all, o.resources...).
|
||||||
Flatten().
|
Flatten().
|
||||||
Latest()
|
Latest()
|
||||||
|
@ -463,6 +463,55 @@ func TestAnnotateObject(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAnnotateObjectFromFile(t *testing.T) {
|
||||||
|
pods, _, _ := testData()
|
||||||
|
|
||||||
|
f, tf, codec := NewAPIFactory()
|
||||||
|
tf.Printer = &testPrinter{}
|
||||||
|
tf.Client = &client.FakeRESTClient{
|
||||||
|
Codec: codec,
|
||||||
|
Client: client.HTTPClientFunc(func(req *http.Request) (*http.Response, error) {
|
||||||
|
switch req.Method {
|
||||||
|
case "GET":
|
||||||
|
switch req.URL.Path {
|
||||||
|
case "/namespaces/test/pods/cassandra":
|
||||||
|
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
case "PUT":
|
||||||
|
switch req.URL.Path {
|
||||||
|
case "/namespaces/test/pods/cassandra":
|
||||||
|
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.Fatalf("unexpected request: %s %#v\n%#v", req.Method, req.URL, req)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
tf.Namespace = "test"
|
||||||
|
tf.ClientConfig = &client.Config{Version: testapi.Version()}
|
||||||
|
buf := bytes.NewBuffer([]byte{})
|
||||||
|
|
||||||
|
options := &AnnotateOptions{}
|
||||||
|
options.filenames = []string{"../../../examples/cassandra/cassandra.yaml"}
|
||||||
|
args := []string{"a=b", "c-"}
|
||||||
|
if err := options.Complete(f, args, buf); 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(); err != nil {
|
||||||
|
t.Fatalf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAnnotateMultipleObjects(t *testing.T) {
|
func TestAnnotateMultipleObjects(t *testing.T) {
|
||||||
pods, _, _ := testData()
|
pods, _, _ := testData()
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ $ kubectl describe nodes kubernetes-minion-emt8.c.myproject.internal
|
|||||||
# Describe a pod
|
# Describe a pod
|
||||||
$ kubectl describe pods/nginx
|
$ kubectl describe pods/nginx
|
||||||
|
|
||||||
# Describe a pod using the data in pod.json.
|
# Describe a pod identified by type and name in "pod.json"
|
||||||
$ kubectl describe -f pod.json
|
$ kubectl describe -f pod.json
|
||||||
|
|
||||||
# Describe all pods
|
# Describe all pods
|
||||||
|
Loading…
Reference in New Issue
Block a user