Merge pull request #12388 from feihujiang/kubectlPatchAcceptFileNameParam

Auto commit by PR queue bot
This commit is contained in:
Brendan Burns
2015-08-13 11:49:41 -07:00
6 changed files with 78 additions and 14 deletions

View File

@@ -17,11 +17,12 @@ limitations under the License.
package cmd
import (
"fmt"
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/kubectl"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
)
@@ -36,13 +37,16 @@ Please refer to the models in https://htmlpreview.github.io/?https://github.com/
# Partially update a node using strategic merge patch
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'
# Partially update a node identified by the type and name specified in "node.json" using strategic merge patch
kubectl patch -f node.json -p '{"spec":{"unschedulable":true}}'
# Update a container's image; spec.containers[*].name is required because it's a merge key
kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'`
)
func NewCmdPatch(f *cmdutil.Factory, out io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "patch TYPE NAME -p PATCH",
Use: "patch (-f FILENAME | TYPE NAME) -p PATCH",
Short: "Update field(s) of a resource by stdin.",
Long: patch_long,
Example: patch_example,
@@ -56,11 +60,14 @@ func NewCmdPatch(f *cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().StringP("patch", "p", "", "The patch to be applied to the resource JSON file.")
cmd.MarkFlagRequired("patch")
cmdutil.AddOutputFlagsForMutation(cmd)
usage := "Filename, directory, or URL to a file identifying the resource to update"
kubectl.AddJsonFilenameFlag(cmd, usage)
return cmd
}
func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, shortOutput bool) error {
cmdNamespace, _, err := f.DefaultNamespace()
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
@@ -74,6 +81,7 @@ func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
r := resource.NewBuilder(mapper, typer, f.ClientMapperForCommand()).
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, cmdutil.GetFlagStringSlice(cmd, "filename")...).
ResourceTypeOrNameArgs(false, args...).
Flatten().
Do()
@@ -81,20 +89,21 @@ func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
if err != nil {
return err
}
mapping, err := r.ResourceMapping()
if err != nil {
return err
}
client, err := f.RESTClient(mapping)
if err != nil {
return err
}
infos, err := r.Infos()
if err != nil {
return err
}
name, namespace := infos[0].Name, infos[0].Namespace
if len(infos) > 1 {
return fmt.Errorf("multiple resources provided")
}
info := infos[0]
name, namespace := info.Name, info.Namespace
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, []byte(patch))

View File

@@ -55,3 +55,36 @@ func TestPatchObject(t *testing.T) {
t.Errorf("unexpected output: %s", buf.String())
}
}
func TestPatchObjectFromFile(t *testing.T) {
_, svc, _ := 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 p, m := req.URL.Path, req.Method; {
case p == "/namespaces/test/services/frontend" && (m == "PATCH" || m == "GET"):
return &http.Response{StatusCode: 200, Body: objBody(codec, &svc.Items[0])}, nil
default:
t.Fatalf("unexpected request: %#v\n%#v", req.URL, req)
return nil, nil
}
}),
}
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdPatch(f, buf)
cmd.Flags().Set("namespace", "test")
cmd.Flags().Set("patch", `{"spec":{"type":"NodePort"}}`)
cmd.Flags().Set("output", "name")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.yaml")
cmd.Run(cmd, []string{})
// uses the name from the file, not the response
if buf.String() != "frontend\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}