reenable patch serverside using strategic-merge-patch

pull/6/head
Mike Danese 2015-06-17 16:56:55 -07:00
parent 458cbd3b5d
commit 3de11e2fa8
8 changed files with 47 additions and 28 deletions

View File

@ -337,10 +337,12 @@ _kubectl_update()
flags_completion+=("__handle_filename_extension_flag json|yaml|yml") flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
flags+=("--help") flags+=("--help")
flags+=("-h") flags+=("-h")
flags+=("--patch=")
must_have_one_flag=() must_have_one_flag=()
must_have_one_flag+=("--filename=") must_have_one_flag+=("--filename=")
must_have_one_flag+=("-f") must_have_one_flag+=("-f")
must_have_one_flag+=("--patch=")
must_have_one_noun=() must_have_one_noun=()
} }

View File

@ -21,6 +21,9 @@ $ kubectl update -f pod.json
// Update a pod based on the JSON passed into stdin. // Update a pod based on the JSON passed into stdin.
$ cat pod.json | kubectl update -f - $ cat pod.json | kubectl update -f -
// Partially update a node using strategic merge patch
kubectl --api-version=v1 update node k8s-node-1 --patch='{"spec":{"unschedulable":true}}'
``` ```
### Options ### Options
@ -28,6 +31,7 @@ $ cat pod.json | kubectl update -f -
``` ```
-f, --filename=[]: Filename, directory, or URL to file to use to update the resource. -f, --filename=[]: Filename, directory, or URL to file to use to update the resource.
-h, --help=false: help for update -h, --help=false: help for update
--patch="": A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated.
``` ```
### Options inherited from parent commands ### Options inherited from parent commands
@ -62,6 +66,6 @@ $ cat pod.json | kubectl update -f -
### SEE ALSO ### SEE ALSO
* [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-05-29 01:11:24.431126385 +0000 UTC ###### Auto generated by spf13/cobra at 2015-06-18 19:03:00.935576604 +0000 UTC
[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/kubectl_update.md?pixel)]() [![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/kubectl_update.md?pixel)]()

View File

@ -28,6 +28,10 @@ JSON and YAML formats are accepted.
\fB\-h\fP, \fB\-\-help\fP=false \fB\-h\fP, \fB\-\-help\fP=false
help for update help for update
.PP
\fB\-\-patch\fP=""
A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated.
.SH OPTIONS INHERITED FROM PARENT COMMANDS .SH OPTIONS INHERITED FROM PARENT COMMANDS
.PP .PP
@ -138,6 +142,9 @@ $ kubectl update \-f pod.json
// Update a pod based on the JSON passed into stdin. // Update a pod based on the JSON passed into stdin.
$ cat pod.json | kubectl update \-f \- $ cat pod.json | kubectl update \-f \-
// Partially update a node using strategic merge patch
kubectl \-\-api\-version=v1 update node k8s\-node\-1 \-\-patch='\{"spec":\{"unschedulable":true\}\}'
.fi .fi
.RE .RE

View File

@ -20,6 +20,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/testapi"
"github.com/GoogleCloudPlatform/kubernetes/pkg/runtime" "github.com/GoogleCloudPlatform/kubernetes/pkg/runtime"
) )
@ -47,6 +48,10 @@ func (c *FakeRESTClient) Put() *Request {
return NewRequest(c, "PUT", &url.URL{Host: "localhost"}, testapi.Version(), c.Codec) return NewRequest(c, "PUT", &url.URL{Host: "localhost"}, testapi.Version(), c.Codec)
} }
func (c *FakeRESTClient) Patch(_ api.PatchType) *Request {
return NewRequest(c, "PATCH", &url.URL{Host: "localhost"}, testapi.Version(), c.Codec)
}
func (c *FakeRESTClient) Post() *Request { func (c *FakeRESTClient) Post() *Request {
return NewRequest(c, "POST", &url.URL{Host: "localhost"}, testapi.Version(), c.Codec) return NewRequest(c, "POST", &url.URL{Host: "localhost"}, testapi.Version(), c.Codec)
} }

View File

@ -22,6 +22,7 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util" cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
@ -36,7 +37,10 @@ JSON and YAML formats are accepted.`
$ kubectl update -f pod.json $ kubectl update -f pod.json
// Update a pod based on the JSON passed into stdin. // Update a pod based on the JSON passed into stdin.
$ cat pod.json | kubectl update -f -` $ cat pod.json | kubectl update -f -
// Partially update a node using strategic merge patch
kubectl --api-version=v1 update node k8s-node-1 --patch='{"spec":{"unschedulable":true}}'`
) )
func NewCmdUpdate(f *cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdUpdate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
@ -54,9 +58,8 @@ func NewCmdUpdate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
usage := "Filename, directory, or URL to file to use to update the resource." usage := "Filename, directory, or URL to file to use to update the resource."
kubectl.AddJsonFilenameFlag(cmd, &filenames, usage) kubectl.AddJsonFilenameFlag(cmd, &filenames, usage)
cmd.MarkFlagRequired("filename") cmd.MarkFlagRequired("filename")
// TODO: re-enable --patch and make it use strategic-merge-patch cmd.Flags().String("patch", "", "A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated.")
// cmd.Flags().String("patch", "", "A JSON document to override the existing resource. The resource is downloaded, patched with the JSON, then updated.") cmd.MarkFlagRequired("patch")
// cmd.MarkFlagRequired("patch")
return cmd return cmd
} }
@ -71,7 +74,7 @@ func RunUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
return err return err
} }
/* patch := cmdutil.GetFlagString(cmd, "patch") patch := cmdutil.GetFlagString(cmd, "patch")
if len(filenames) == 0 && len(patch) == 0 { if len(filenames) == 0 && len(patch) == 0 {
return cmdutil.UsageError(cmd, "Must specify --filename or --patch to update") return cmdutil.UsageError(cmd, "Must specify --filename or --patch to update")
} }
@ -87,7 +90,7 @@ func RunUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
} }
fmt.Fprintf(out, "%s\n", name) fmt.Fprintf(out, "%s\n", name)
return nil return nil
} */ }
if len(filenames) == 0 { if len(filenames) == 0 {
return cmdutil.UsageError(cmd, "Must specify --filename to update") return cmdutil.UsageError(cmd, "Must specify --filename to update")
} }
@ -154,21 +157,6 @@ func updateWithPatch(cmd *cobra.Command, args []string, f *cmdutil.Factory, patc
name, namespace := infos[0].Name, infos[0].Namespace name, namespace := infos[0].Name, infos[0].Namespace
helper := resource.NewHelper(client, mapping) helper := resource.NewHelper(client, mapping)
obj, err := helper.Get(namespace, name) _, err = helper.Patch(namespace, name, api.StrategicMergePatchType, []byte(patch))
if err != nil {
return "", err
}
patchedObj, err := cmdutil.Merge(obj, patch, mapping.Kind)
if err != nil {
return "", err
}
data, err := helper.Codec.Encode(patchedObj)
if err != nil {
return "", err
}
_, err = helper.Update(namespace, name, true, data)
return name, err return name, err
} }

View File

@ -17,6 +17,7 @@ limitations under the License.
package kubectl package kubectl
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
) )
@ -25,6 +26,7 @@ import (
type RESTClient interface { type RESTClient interface {
Get() *client.Request Get() *client.Request
Post() *client.Request Post() *client.Request
Patch(api.PatchType) *client.Request
Delete() *client.Request Delete() *client.Request
Put() *client.Request Put() *client.Request
} }

View File

@ -17,6 +17,7 @@ limitations under the License.
package resource package resource
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields" "github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
"github.com/GoogleCloudPlatform/kubernetes/pkg/labels" "github.com/GoogleCloudPlatform/kubernetes/pkg/labels"
@ -43,11 +44,10 @@ type Helper struct {
// NewHelper creates a Helper from a ResourceMapping // NewHelper creates a Helper from a ResourceMapping
func NewHelper(client RESTClient, mapping *meta.RESTMapping) *Helper { func NewHelper(client RESTClient, mapping *meta.RESTMapping) *Helper {
return &Helper{ return &Helper{
RESTClient: client, RESTClient: client,
Resource: mapping.Resource, Resource: mapping.Resource,
Codec: mapping.Codec, Codec: mapping.Codec,
Versioner: mapping.MetadataAccessor, Versioner: mapping.MetadataAccessor,
NamespaceScoped: mapping.Scope.Name() == meta.RESTScopeNameNamespace, NamespaceScoped: mapping.Scope.Name() == meta.RESTScopeNameNamespace,
} }
} }
@ -133,6 +133,15 @@ func (m *Helper) Create(namespace string, modify bool, data []byte) (runtime.Obj
func (m *Helper) createResource(c RESTClient, resource, namespace string, data []byte) (runtime.Object, error) { func (m *Helper) createResource(c RESTClient, resource, namespace string, data []byte) (runtime.Object, error) {
return c.Post().NamespaceIfScoped(namespace, m.NamespaceScoped).Resource(resource).Body(data).Do().Get() return c.Post().NamespaceIfScoped(namespace, m.NamespaceScoped).Resource(resource).Body(data).Do().Get()
} }
func (m *Helper) Patch(namespace, name string, pt api.PatchType, data []byte) (runtime.Object, error) {
return m.RESTClient.Patch(pt).
NamespaceIfScoped(namespace, m.NamespaceScoped).
Resource(m.Resource).
Name(name).
Body(data).
Do().
Get()
}
func (m *Helper) Update(namespace, name string, overwrite bool, data []byte) (runtime.Object, error) { func (m *Helper) Update(namespace, name string, overwrite bool, data []byte) (runtime.Object, error) {
c := m.RESTClient c := m.RESTClient

View File

@ -17,6 +17,7 @@ limitations under the License.
package resource package resource
import ( import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta" "github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/client" "github.com/GoogleCloudPlatform/kubernetes/pkg/client"
) )
@ -26,6 +27,7 @@ import (
type RESTClient interface { type RESTClient interface {
Get() *client.Request Get() *client.Request
Post() *client.Request Post() *client.Request
Patch(api.PatchType) *client.Request
Delete() *client.Request Delete() *client.Request
Put() *client.Request Put() *client.Request
} }