Merge pull request #15597 from caesarxuchao/annotate-patch

let kubectl annotate use patch instead of replace
This commit is contained in:
Piotr Szczesniak 2015-10-16 07:29:22 +02:00
commit 4b983584a8
2 changed files with 37 additions and 18 deletions

View File

@ -18,6 +18,7 @@ package cmd
import ( import (
"bytes" "bytes"
"encoding/json"
"fmt" "fmt"
"io" "io"
"strings" "strings"
@ -28,6 +29,7 @@ import (
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"
"k8s.io/kubernetes/pkg/util/strategicpatch"
) )
// AnnotateOptions have the data required to perform the annotate operation // AnnotateOptions have the data required to perform the annotate operation
@ -91,7 +93,7 @@ func NewCmdAnnotate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
if err := options.Validate(args); err != nil { if err := options.Validate(args); err != nil {
cmdutil.CheckErr(cmdutil.UsageError(cmd, err.Error())) cmdutil.CheckErr(cmdutil.UsageError(cmd, err.Error()))
} }
if err := options.RunAnnotate(); err != nil { if err := options.RunAnnotate(f); err != nil {
cmdutil.CheckErr(err) cmdutil.CheckErr(err)
} }
}, },
@ -167,26 +169,43 @@ func (o AnnotateOptions) Validate(args []string) error {
} }
// RunAnnotate does the work // RunAnnotate does the work
func (o AnnotateOptions) RunAnnotate() error { func (o AnnotateOptions) RunAnnotate(f *cmdutil.Factory) error {
r := o.builder.Do() r := o.builder.Do()
if err := r.Err(); err != nil { if err := r.Err(); err != nil {
return err return err
} }
return r.Visit(func(info *resource.Info, err error) error { return r.Visit(func(info *resource.Info, err error) error {
if err != nil { if err != nil {
return err return err
} }
_, uErr := cmdutil.UpdateObject(info, func(obj runtime.Object) error {
err := o.updateAnnotations(obj) name, namespace, obj := info.Name, info.Namespace, info.Object
if err != nil { oldData, err := json.Marshal(obj)
return err if err != nil {
} return err
return nil
})
if uErr != nil {
return uErr
} }
return nil if err := o.updateAnnotations(obj); err != nil {
return err
}
newData, err := json.Marshal(obj)
if err != nil {
return err
}
patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, obj)
if err != nil {
return err
}
mapping := info.ResourceMapping()
client, err := f.RESTClient(mapping)
if err != nil {
return err
}
helper := resource.NewHelper(client, mapping)
_, err = helper.Patch(namespace, name, api.StrategicMergePatchType, patchBytes)
return err
}) })
} }

View File

@ -433,7 +433,7 @@ func TestAnnotateObject(t *testing.T) {
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
} }
case "PUT": case "PATCH":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/pods/foo": case "/namespaces/test/pods/foo":
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
@ -458,7 +458,7 @@ func TestAnnotateObject(t *testing.T) {
if err := options.Validate(args); err != nil { if err := options.Validate(args); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if err := options.RunAnnotate(); err != nil { if err := options.RunAnnotate(f); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
} }
@ -480,7 +480,7 @@ func TestAnnotateObjectFromFile(t *testing.T) {
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
} }
case "PUT": case "PATCH":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/pods/cassandra": case "/namespaces/test/pods/cassandra":
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
@ -506,7 +506,7 @@ func TestAnnotateObjectFromFile(t *testing.T) {
if err := options.Validate(args); err != nil { if err := options.Validate(args); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if err := options.RunAnnotate(); err != nil { if err := options.RunAnnotate(f); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
} }
@ -528,7 +528,7 @@ func TestAnnotateMultipleObjects(t *testing.T) {
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req) t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil return nil, nil
} }
case "PUT": case "PATCH":
switch req.URL.Path { switch req.URL.Path {
case "/namespaces/test/pods/foo": case "/namespaces/test/pods/foo":
return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil return &http.Response{StatusCode: 200, Body: objBody(codec, &pods.Items[0])}, nil
@ -556,7 +556,7 @@ func TestAnnotateMultipleObjects(t *testing.T) {
if err := options.Validate(args); err != nil { if err := options.Validate(args); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
if err := options.RunAnnotate(); err != nil { if err := options.RunAnnotate(f); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
} }