diff --git a/docs/kubectl.md b/docs/kubectl.md index 3423bd8746..265086036d 100644 --- a/docs/kubectl.md +++ b/docs/kubectl.md @@ -253,7 +253,7 @@ Usage: --client-key="": Path to a client key file for TLS. --cluster="": The name of the kubeconfig cluster to use --context="": The name of the kubeconfig context to use - -f, --filename="": Filename 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 --insecure-skip-tls-verify=false: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure. --kubeconfig="": Path to the kubeconfig file to use for CLI requests. diff --git a/pkg/kubectl/cmd/update.go b/pkg/kubectl/cmd/update.go index 6b191533f8..1996e1f91a 100644 --- a/pkg/kubectl/cmd/update.go +++ b/pkg/kubectl/cmd/update.go @@ -21,10 +21,14 @@ import ( "io" "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource" + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" "github.com/spf13/cobra" ) func (f *Factory) NewCmdUpdate(out io.Writer) *cobra.Command { + flags := &struct { + Filenames util.StringList + }{} cmd := &cobra.Command{ Use: "update -f filename", Short: "Update a resource by filename or stdin", @@ -42,25 +46,52 @@ Examples: $ kubectl update pods my-pod --patch='{ "apiVersion": "v1beta1", "desiredState": { "manifest": [{ "cpu": 100 }]}}' `, Run: func(cmd *cobra.Command, args []string) { - filename := GetFlagString(cmd, "filename") + schema, err := f.Validator(cmd) + checkErr(err) + + cmdNamespace, err := f.DefaultNamespace(cmd) + checkErr(err) + + mapper, typer := f.Object(cmd) + r := resource.NewBuilder(mapper, typer, ClientMapperForCommand(cmd, f)). + ContinueOnError(). + NamespaceParam(cmdNamespace).RequireNamespace(). + FilenameParam(flags.Filenames...). + Flatten(). + Do() + patch := GetFlagString(cmd, "patch") - if len(filename) == 0 && len(patch) == 0 { + if len(flags.Filenames) == 0 && len(patch) == 0 { usageError(cmd, "Must specify --filename or --patch to update") } - if len(filename) != 0 && len(patch) != 0 { + if len(flags.Filenames) != 0 && len(patch) != 0 { usageError(cmd, "Can not specify both --filename and --patch") } - var name string - if len(filename) > 0 { - name = updateWithFile(cmd, f, filename) + if len(flags.Filenames) > 0 { + err := r.Visit(func(info *resource.Info) error { + data, err := info.Mapping.Codec.Encode(info.Object) + if err != nil { + return err + } + if err := schema.ValidateBytes(data); err != nil { + return err + } + if err := resource.NewHelper(info.Client, info.Mapping). + Update(info.Namespace, info.Name, true, data); err != nil { + return err + } + fmt.Fprintf(out, "%s\n", info.Name) + return nil + }) + checkErr(err) } else { - name = updateWithPatch(cmd, args, f, patch) + name := updateWithPatch(cmd, args, f, patch) + fmt.Fprintf(out, "%s\n", name) } - fmt.Fprintf(out, "%s\n", name) }, } - cmd.Flags().StringP("filename", "f", "", "Filename or URL to file to use to update the resource") + cmd.Flags().VarP(&flags.Filenames, "filename", "f", "Filename, directory, or URL to file to use to update the resource") cmd.Flags().String("patch", "", "A JSON document to override the existing resource. The resource is downloaded, then patched with the JSON, the updated") return cmd } @@ -87,28 +118,3 @@ func updateWithPatch(cmd *cobra.Command, args []string, f *Factory, patch string checkErr(err) return name } - -func updateWithFile(cmd *cobra.Command, f *Factory, filename string) string { - schema, err := f.Validator(cmd) - checkErr(err) - mapper, typer := f.Object(cmd) - - clientConfig, err := f.ClientConfig(cmd) - checkErr(err) - cmdApiVersion := clientConfig.Version - - mapping, namespace, name, data := ResourceFromFile(filename, typer, mapper, schema, cmdApiVersion) - - client, err := f.RESTClient(cmd, mapping) - checkErr(err) - - cmdNamespace, err := f.DefaultNamespace(cmd) - checkErr(err) - err = CompareNamespace(cmdNamespace, namespace) - checkErr(err) - - err = resource.NewHelper(client, mapping).Update(namespace, name, true, data) - checkErr(err) - - return name -}