mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #33250 from ymqytw/edit_before_create
Automatic merge from submit-queue support editing before creating resource Support `kubectl create -f config.yaml --edit` Support editing before creating resource from files, urls and stdin. The behavior is similar to `kubectl edit` It won't create anything when edit make no change. partial: #18064 Based on: #33686 and #33973 ```release-note Support editing before creating resource from files, urls and stdin, e.g. `kubectl create -f config.yaml --edit` It won't create anything when edit make no change. ```
This commit is contained in:
		@@ -720,6 +720,25 @@ runTests() {
 | 
				
			|||||||
  # Pre-condition: no POD exists
 | 
					  # Pre-condition: no POD exists
 | 
				
			||||||
  create_and_use_new_namespace
 | 
					  create_and_use_new_namespace
 | 
				
			||||||
  kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" ''
 | 
					  kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" ''
 | 
				
			||||||
 | 
					  ## kubectl create --edit can update the image field of a POD. tmp-editor.sh is a fake editor
 | 
				
			||||||
 | 
					  TEMP=$(mktemp /tmp/tmp-editor-XXXXXXXX.sh)
 | 
				
			||||||
 | 
					  echo -e "#!/bin/bash\n$SED -i \"s/gcr.io\/google_containers\/serve_hostname/nginx/g\" \$1" > ${TEMP}
 | 
				
			||||||
 | 
					  chmod +x ${TEMP}
 | 
				
			||||||
 | 
					  # Command
 | 
				
			||||||
 | 
					  EDITOR=${TEMP} kubectl create --edit -f test/fixtures/doc-yaml/admin/limitrange/valid-pod.yaml "${kube_flags[@]}"
 | 
				
			||||||
 | 
					  # Post-condition: valid-pod POD is created and has image gcr.io/google_containers/serve_hostname
 | 
				
			||||||
 | 
					  kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" 'valid-pod:'
 | 
				
			||||||
 | 
					  kube::test::get_object_assert pods "{{range.items}}{{$image_field}}:{{end}}" 'nginx:'
 | 
				
			||||||
 | 
					  # Clean up
 | 
				
			||||||
 | 
					  rm ${TEMP}
 | 
				
			||||||
 | 
					  kubectl delete pods/valid-pod "${kube_flags[@]}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ## kubectl create --edit won't create anything if user makes no changes
 | 
				
			||||||
 | 
					  [ "$(EDITOR=cat kubectl create --edit -f test/fixtures/doc-yaml/admin/limitrange/valid-pod.yaml -o json 2>&1 | grep 'Edit cancelled')" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ## Create valid-pod POD
 | 
				
			||||||
 | 
					  # Pre-condition: no POD exists
 | 
				
			||||||
 | 
					  kube::test::get_object_assert pods "{{range.items}}{{$id_field}}:{{end}}" ''
 | 
				
			||||||
  # Command
 | 
					  # Command
 | 
				
			||||||
  kubectl create -f test/fixtures/doc-yaml/admin/limitrange/valid-pod.yaml "${kube_flags[@]}"
 | 
					  kubectl create -f test/fixtures/doc-yaml/admin/limitrange/valid-pod.yaml "${kube_flags[@]}"
 | 
				
			||||||
  # Post-condition: valid-pod POD is created
 | 
					  # Post-condition: valid-pod POD is created
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -221,7 +221,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			Message: "Basic Commands (Beginner):",
 | 
								Message: "Basic Commands (Beginner):",
 | 
				
			||||||
			Commands: []*cobra.Command{
 | 
								Commands: []*cobra.Command{
 | 
				
			||||||
				NewCmdCreate(f, out),
 | 
									NewCmdCreate(f, out, err),
 | 
				
			||||||
				NewCmdExposeService(f, out),
 | 
									NewCmdExposeService(f, out),
 | 
				
			||||||
				NewCmdRun(f, in, out, err),
 | 
									NewCmdRun(f, in, out, err),
 | 
				
			||||||
				set.NewCmdSet(f, out, err),
 | 
									set.NewCmdSet(f, out, err),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@ package cmd
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
 | 
						gruntime "runtime"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -41,10 +42,13 @@ var (
 | 
				
			|||||||
		kubectl create -f ./pod.json
 | 
							kubectl create -f ./pod.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		# Create a pod based on the JSON passed into stdin.
 | 
							# Create a pod based on the JSON passed into stdin.
 | 
				
			||||||
		cat pod.json | kubectl create -f -`)
 | 
							cat pod.json | kubectl create -f -
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							# Edit the data in docker-registry.yaml in JSON using the v1 API format then create the resource using the edited data.
 | 
				
			||||||
 | 
							kubectl create -f docker-registry.yaml --edit --output-version=v1 -o json`)
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewCmdCreate(f cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
					func NewCmdCreate(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
 | 
				
			||||||
	options := &resource.FilenameOptions{}
 | 
						options := &resource.FilenameOptions{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd := &cobra.Command{
 | 
						cmd := &cobra.Command{
 | 
				
			||||||
@@ -58,8 +62,7 @@ func NewCmdCreate(f cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
				
			|||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			cmdutil.CheckErr(ValidateArgs(cmd, args))
 | 
								cmdutil.CheckErr(ValidateArgs(cmd, args))
 | 
				
			||||||
			cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
 | 
								cmdutil.CheckErr(RunCreate(f, cmd, out, errOut, options))
 | 
				
			||||||
			cmdutil.CheckErr(RunCreate(f, cmd, out, options))
 | 
					 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -68,6 +71,8 @@ func NewCmdCreate(f cmdutil.Factory, out io.Writer) *cobra.Command {
 | 
				
			|||||||
	cmd.MarkFlagRequired("filename")
 | 
						cmd.MarkFlagRequired("filename")
 | 
				
			||||||
	cmdutil.AddValidateFlags(cmd)
 | 
						cmdutil.AddValidateFlags(cmd)
 | 
				
			||||||
	cmdutil.AddPrinterFlags(cmd)
 | 
						cmdutil.AddPrinterFlags(cmd)
 | 
				
			||||||
 | 
						cmd.Flags().Bool("edit", false, "Edit the API resource before creating")
 | 
				
			||||||
 | 
						cmd.Flags().Bool("windows-line-endings", gruntime.GOOS == "windows", "Only relevant if --edit=true. Use Windows line-endings (default Unix line-endings)")
 | 
				
			||||||
	cmdutil.AddApplyAnnotationFlags(cmd)
 | 
						cmdutil.AddApplyAnnotationFlags(cmd)
 | 
				
			||||||
	cmdutil.AddRecordFlag(cmd)
 | 
						cmdutil.AddRecordFlag(cmd)
 | 
				
			||||||
	cmdutil.AddDryRunFlag(cmd)
 | 
						cmdutil.AddDryRunFlag(cmd)
 | 
				
			||||||
@@ -91,7 +96,10 @@ func ValidateArgs(cmd *cobra.Command, args []string) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RunCreate(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *resource.FilenameOptions) error {
 | 
					func RunCreate(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, options *resource.FilenameOptions) error {
 | 
				
			||||||
 | 
						if cmdutil.GetFlagBool(cmd, "edit") {
 | 
				
			||||||
 | 
							return RunEditOnCreate(f, out, errOut, cmd, options)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir"))
 | 
						schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"), cmdutil.GetFlagString(cmd, "schema-cache-dir"))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
@@ -159,6 +167,10 @@ func RunCreate(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, options *re
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func RunEditOnCreate(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, options *resource.FilenameOptions) error {
 | 
				
			||||||
 | 
						return runEdit(f, out, errOut, cmd, []string{}, options, EditBeforeCreateMode)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// createAndRefresh creates an object from input info and refreshes info with that object
 | 
					// createAndRefresh creates an object from input info and refreshes info with that object
 | 
				
			||||||
func createAndRefresh(info *resource.Info) error {
 | 
					func createAndRefresh(info *resource.Info) error {
 | 
				
			||||||
	obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)
 | 
						obj, err := resource.NewHelper(info.Client, info.Mapping).Create(info.Namespace, true, info.Object)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,9 +29,10 @@ import (
 | 
				
			|||||||
func TestExtraArgsFail(t *testing.T) {
 | 
					func TestExtraArgsFail(t *testing.T) {
 | 
				
			||||||
	initTestErrorHandler(t)
 | 
						initTestErrorHandler(t)
 | 
				
			||||||
	buf := bytes.NewBuffer([]byte{})
 | 
						buf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
						errBuf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f, _, _, _ := cmdtesting.NewAPIFactory()
 | 
						f, _, _, _ := cmdtesting.NewAPIFactory()
 | 
				
			||||||
	c := NewCmdCreate(f, buf)
 | 
						c := NewCmdCreate(f, buf, errBuf)
 | 
				
			||||||
	if ValidateArgs(c, []string{"rc"}) == nil {
 | 
						if ValidateArgs(c, []string{"rc"}) == nil {
 | 
				
			||||||
		t.Errorf("unexpected non-error")
 | 
							t.Errorf("unexpected non-error")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -59,8 +60,9 @@ func TestCreateObject(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	tf.Namespace = "test"
 | 
						tf.Namespace = "test"
 | 
				
			||||||
	buf := bytes.NewBuffer([]byte{})
 | 
						buf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
						errBuf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd := NewCmdCreate(f, buf)
 | 
						cmd := NewCmdCreate(f, buf, errBuf)
 | 
				
			||||||
	cmd.Flags().Set("filename", "../../../examples/guestbook/legacy/redis-master-controller.yaml")
 | 
						cmd.Flags().Set("filename", "../../../examples/guestbook/legacy/redis-master-controller.yaml")
 | 
				
			||||||
	cmd.Flags().Set("output", "name")
 | 
						cmd.Flags().Set("output", "name")
 | 
				
			||||||
	cmd.Run(cmd, []string{})
 | 
						cmd.Run(cmd, []string{})
 | 
				
			||||||
@@ -94,8 +96,9 @@ func TestCreateMultipleObject(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	tf.Namespace = "test"
 | 
						tf.Namespace = "test"
 | 
				
			||||||
	buf := bytes.NewBuffer([]byte{})
 | 
						buf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
						errBuf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd := NewCmdCreate(f, buf)
 | 
						cmd := NewCmdCreate(f, buf, errBuf)
 | 
				
			||||||
	cmd.Flags().Set("filename", "../../../examples/guestbook/legacy/redis-master-controller.yaml")
 | 
						cmd.Flags().Set("filename", "../../../examples/guestbook/legacy/redis-master-controller.yaml")
 | 
				
			||||||
	cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.yaml")
 | 
						cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.yaml")
 | 
				
			||||||
	cmd.Flags().Set("output", "name")
 | 
						cmd.Flags().Set("output", "name")
 | 
				
			||||||
@@ -129,8 +132,9 @@ func TestCreateDirectory(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	tf.Namespace = "test"
 | 
						tf.Namespace = "test"
 | 
				
			||||||
	buf := bytes.NewBuffer([]byte{})
 | 
						buf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
						errBuf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd := NewCmdCreate(f, buf)
 | 
						cmd := NewCmdCreate(f, buf, errBuf)
 | 
				
			||||||
	cmd.Flags().Set("filename", "../../../examples/guestbook/legacy")
 | 
						cmd.Flags().Set("filename", "../../../examples/guestbook/legacy")
 | 
				
			||||||
	cmd.Flags().Set("output", "name")
 | 
						cmd.Flags().Set("output", "name")
 | 
				
			||||||
	cmd.Run(cmd, []string{})
 | 
						cmd.Run(cmd, []string{})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -118,12 +118,16 @@ func NewCmdEdit(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func RunEdit(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args []string, options *resource.FilenameOptions) error {
 | 
					func RunEdit(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args []string, options *resource.FilenameOptions) error {
 | 
				
			||||||
 | 
						return runEdit(f, out, errOut, cmd, args, options, NormalEditMode)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func runEdit(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args []string, options *resource.FilenameOptions, editMode EditMode) error {
 | 
				
			||||||
	o, err := getPrinter(cmd)
 | 
						o, err := getPrinter(cmd)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mapper, resourceMapper, r, cmdNamespace, err := getMapperAndResult(f, args, options)
 | 
						mapper, resourceMapper, r, cmdNamespace, err := getMapperAndResult(f, args, options, editMode)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -192,14 +196,15 @@ func RunEdit(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
 | 
				
			|||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return preservedFile(err, results.file, errOut)
 | 
									return preservedFile(err, results.file, errOut)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								if editMode == NormalEditMode || containsError {
 | 
				
			||||||
				if bytes.Equal(stripComments(editedDiff), stripComments(edited)) {
 | 
									if bytes.Equal(stripComments(editedDiff), stripComments(edited)) {
 | 
				
			||||||
					// Ugly hack right here. We will hit this either (1) when we try to
 | 
										// Ugly hack right here. We will hit this either (1) when we try to
 | 
				
			||||||
					// save the same changes we tried to save in the previous iteration
 | 
										// save the same changes we tried to save in the previous iteration
 | 
				
			||||||
					// which means our changes are invalid or (2) when we exit the second
 | 
										// which means our changes are invalid or (2) when we exit the second
 | 
				
			||||||
					// time. The second case is more usual so we can probably live with it.
 | 
										// time. The second case is more usual so we can probably live with it.
 | 
				
			||||||
					// TODO: A less hacky fix would be welcome :)
 | 
										// TODO: A less hacky fix would be welcome :)
 | 
				
			||||||
				fmt.Fprintln(errOut, "Edit cancelled, no valid changes were saved.")
 | 
										return preservedFile(fmt.Errorf("%s", "Edit cancelled, no valid changes were saved."), file, errOut)
 | 
				
			||||||
				return nil
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// cleanup any file from the previous pass
 | 
								// cleanup any file from the previous pass
 | 
				
			||||||
@@ -229,6 +234,7 @@ func RunEdit(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
 | 
				
			|||||||
				fmt.Fprintln(errOut, "Edit cancelled, no changes made.")
 | 
									fmt.Fprintln(errOut, "Edit cancelled, no changes made.")
 | 
				
			||||||
				return nil
 | 
									return nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			lines, err := hasLines(bytes.NewBuffer(edited))
 | 
								lines, err := hasLines(bytes.NewBuffer(edited))
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return preservedFile(err, file, errOut)
 | 
									return preservedFile(err, file, errOut)
 | 
				
			||||||
@@ -271,7 +277,14 @@ func RunEdit(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args
 | 
				
			|||||||
				meta.SetList(updates.Object, mutatedObjects)
 | 
									meta.SetList(updates.Object, mutatedObjects)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								switch editMode {
 | 
				
			||||||
 | 
								case NormalEditMode:
 | 
				
			||||||
				err = visitToPatch(originalObj, updates, mapper, resourceMapper, encoder, out, errOut, defaultVersion, &results, file)
 | 
									err = visitToPatch(originalObj, updates, mapper, resourceMapper, encoder, out, errOut, defaultVersion, &results, file)
 | 
				
			||||||
 | 
								case EditBeforeCreateMode:
 | 
				
			||||||
 | 
									err = visitToCreate(updates, mapper, resourceMapper, out, errOut, defaultVersion, &results, file)
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									err = fmt.Errorf("Not supported edit mode %q", editMode)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return preservedFile(err, results.file, errOut)
 | 
									return preservedFile(err, results.file, errOut)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -315,7 +328,8 @@ func getPrinter(cmd *cobra.Command) (*editPrinterOptions, error) {
 | 
				
			|||||||
			ext:       ".json",
 | 
								ext:       ".json",
 | 
				
			||||||
			addHeader: false,
 | 
								addHeader: false,
 | 
				
			||||||
		}, nil
 | 
							}, nil
 | 
				
			||||||
	case "yaml":
 | 
						// If flag -o is not specified, use yaml as default
 | 
				
			||||||
 | 
						case "yaml", "":
 | 
				
			||||||
		return &editPrinterOptions{
 | 
							return &editPrinterOptions{
 | 
				
			||||||
			printer:   &kubectl.YAMLPrinter{},
 | 
								printer:   &kubectl.YAMLPrinter{},
 | 
				
			||||||
			ext:       ".yaml",
 | 
								ext:       ".yaml",
 | 
				
			||||||
@@ -326,13 +340,24 @@ func getPrinter(cmd *cobra.Command) (*editPrinterOptions, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getMapperAndResult(f cmdutil.Factory, args []string, options *resource.FilenameOptions) (meta.RESTMapper, *resource.Mapper, *resource.Result, string, error) {
 | 
					func getMapperAndResult(f cmdutil.Factory, args []string, options *resource.FilenameOptions, editMode EditMode) (meta.RESTMapper, *resource.Mapper, *resource.Result, string, error) {
 | 
				
			||||||
	cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
 | 
						cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, nil, nil, "", err
 | 
							return nil, nil, nil, "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						var mapper meta.RESTMapper
 | 
				
			||||||
	mapper, typer := f.Object()
 | 
						var typer runtime.ObjectTyper
 | 
				
			||||||
 | 
						switch editMode {
 | 
				
			||||||
 | 
						case NormalEditMode:
 | 
				
			||||||
 | 
							mapper, typer = f.Object()
 | 
				
			||||||
 | 
						case EditBeforeCreateMode:
 | 
				
			||||||
 | 
							mapper, typer, err = f.UnstructuredObject()
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, nil, nil, "", fmt.Errorf("Not supported edit mode %q", editMode)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, nil, nil, "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	resourceMapper := &resource.Mapper{
 | 
						resourceMapper := &resource.Mapper{
 | 
				
			||||||
		ObjectTyper:  typer,
 | 
							ObjectTyper:  typer,
 | 
				
			||||||
		RESTMapper:   mapper,
 | 
							RESTMapper:   mapper,
 | 
				
			||||||
@@ -345,14 +370,21 @@ func getMapperAndResult(f cmdutil.Factory, args []string, options *resource.File
 | 
				
			|||||||
		// compare two different GroupVersions).
 | 
							// compare two different GroupVersions).
 | 
				
			||||||
		Decoder: f.Decoder(false),
 | 
							Decoder: f.Decoder(false),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						var b *resource.Builder
 | 
				
			||||||
	r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
 | 
						switch editMode {
 | 
				
			||||||
		NamespaceParam(cmdNamespace).DefaultNamespace().
 | 
						case NormalEditMode:
 | 
				
			||||||
		FilenameParam(enforceNamespace, options).
 | 
							b = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.ClientForMapping), f.Decoder(true)).
 | 
				
			||||||
			ResourceTypeOrNameArgs(true, args...).
 | 
								ResourceTypeOrNameArgs(true, args...).
 | 
				
			||||||
 | 
								Latest()
 | 
				
			||||||
 | 
						case EditBeforeCreateMode:
 | 
				
			||||||
 | 
							b = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return nil, nil, nil, "", fmt.Errorf("Not supported edit mode %q", editMode)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						r := b.NamespaceParam(cmdNamespace).DefaultNamespace().
 | 
				
			||||||
 | 
							FilenameParam(enforceNamespace, options).
 | 
				
			||||||
		ContinueOnError().
 | 
							ContinueOnError().
 | 
				
			||||||
		Flatten().
 | 
							Flatten().
 | 
				
			||||||
		Latest().
 | 
					 | 
				
			||||||
		Do()
 | 
							Do()
 | 
				
			||||||
	err = r.Err()
 | 
						err = r.Err()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -428,7 +460,7 @@ func visitToPatch(originalObj runtime.Object, updates *resource.Info, mapper met
 | 
				
			|||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			glog.V(4).Infof("Unable to calculate diff, no merge is possible: %v", err)
 | 
								glog.V(4).Infof("Unable to calculate diff, no merge is possible: %v", err)
 | 
				
			||||||
			if strategicpatch.IsPreconditionFailed(err) {
 | 
								if strategicpatch.IsPreconditionFailed(err) {
 | 
				
			||||||
				return preservedFile(nil, file, errOut)
 | 
									return fmt.Errorf("%s", "At least one of apiVersion, kind and name was changed")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -446,6 +478,19 @@ func visitToPatch(originalObj runtime.Object, updates *resource.Info, mapper met
 | 
				
			|||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func visitToCreate(updates *resource.Info, mapper meta.RESTMapper, resourceMapper *resource.Mapper, out, errOut io.Writer, defaultVersion unversioned.GroupVersion, results *editResults, file string) error {
 | 
				
			||||||
 | 
						createVisitor := resource.NewFlattenListVisitor(updates, resourceMapper)
 | 
				
			||||||
 | 
						err := createVisitor.Visit(func(info *resource.Info, incomingErr error) error {
 | 
				
			||||||
 | 
							results.version = defaultVersion
 | 
				
			||||||
 | 
							if err := createAndRefresh(info); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							cmdutil.PrintSuccess(mapper, false, out, info.Mapping.Resource, info.Name, false, "created")
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func visitAnnotation(cmd *cobra.Command, f cmdutil.Factory, updates *resource.Info, resourceMapper *resource.Mapper, encoder runtime.Encoder) ([]runtime.Object, error) {
 | 
					func visitAnnotation(cmd *cobra.Command, f cmdutil.Factory, updates *resource.Info, resourceMapper *resource.Mapper, encoder runtime.Encoder) ([]runtime.Object, error) {
 | 
				
			||||||
	mutatedObjects := []runtime.Object{}
 | 
						mutatedObjects := []runtime.Object{}
 | 
				
			||||||
	annotationVisitor := resource.NewFlattenListVisitor(updates, resourceMapper)
 | 
						annotationVisitor := resource.NewFlattenListVisitor(updates, resourceMapper)
 | 
				
			||||||
@@ -468,6 +513,13 @@ func visitAnnotation(cmd *cobra.Command, f cmdutil.Factory, updates *resource.In
 | 
				
			|||||||
	return mutatedObjects, err
 | 
						return mutatedObjects, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type EditMode string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						NormalEditMode       EditMode = "normal_mode"
 | 
				
			||||||
 | 
						EditBeforeCreateMode EditMode = "edit_before_create_mode"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// editReason preserves a message about the reason this file must be edited again
 | 
					// editReason preserves a message about the reason this file must be edited again
 | 
				
			||||||
type editReason struct {
 | 
					type editReason struct {
 | 
				
			||||||
	head  string
 | 
						head  string
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user