Support --dry-run in kubectl patch command.

This commit is contained in:
Timo Reimann 2018-03-02 01:19:51 +01:00
parent 060a66ae20
commit b9c1fc6f3c

View File

@ -30,7 +30,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/strategicpatch"
"k8s.io/apimachinery/pkg/util/yaml"
@ -49,7 +48,8 @@ var patchTypes = map[string]types.PatchType{"json": types.JSONPatchType, "merge"
type PatchOptions struct {
resource.FilenameOptions
Local bool
Local bool
DryRun bool
OutputFormat string
}
@ -91,6 +91,7 @@ func NewCmdPatch(f cmdutil.Factory, out io.Writer) *cobra.Command {
Example: patchExample,
Run: func(cmd *cobra.Command, args []string) {
options.OutputFormat = cmdutil.GetFlagString(cmd, "output")
options.DryRun = cmdutil.GetFlagBool(cmd, "dry-run")
err := RunPatch(f, out, cmd, args, options)
cmdutil.CheckErr(err)
},
@ -102,6 +103,7 @@ func NewCmdPatch(f cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().String("type", "strategic", fmt.Sprintf("The type of patch being provided; one of %v", sets.StringKeySet(patchTypes).List()))
cmdutil.AddPrinterFlags(cmd)
cmdutil.AddRecordFlag(cmd)
cmdutil.AddDryRunFlag(cmd)
cmdutil.AddInclude3rdPartyFlags(cmd)
usage := "identifying the resource to update"
@ -168,9 +170,7 @@ func RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin
return err
}
if !options.Local {
dataChangedMsg := "not patched"
didPatch := false
if !options.Local && !options.DryRun {
helper := resource.NewHelper(client, mapping)
patchedObj, err := helper.Patch(namespace, name, patchType, patchBytes)
if err != nil {
@ -191,18 +191,7 @@ func RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin
}
count++
oldData, err := json.Marshal(info.Object)
if err != nil {
return err
}
newData, err := json.Marshal(patchedObj)
if err != nil {
return err
}
if !reflect.DeepEqual(oldData, newData) {
didPatch = true
dataChangedMsg = "patched"
}
didPatch := !reflect.DeepEqual(info.Object, patchedObj)
// After computing whether we changed data, refresh the resource info with the resulting object
if err := info.Refresh(patchedObj, true); err != nil {
@ -212,7 +201,7 @@ func RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin
if len(options.OutputFormat) > 0 && options.OutputFormat != "name" {
return cmdutil.PrintObject(cmd, info.Object, out)
}
cmdutil.PrintSuccess(options.OutputFormat == "name", out, info.Object, false, dataChangedMsg)
cmdutil.PrintSuccess(options.OutputFormat == "name", out, info.Object, false, patchOperation(didPatch))
// if object was not successfully patched, exit with error code 1
if !didPatch {
@ -239,14 +228,24 @@ func RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin
return err
}
didPatch := !reflect.DeepEqual(info.Object, targetObj)
// TODO: if we ever want to go generic, this allows a clean -o yaml without trying to print columns or anything
// rawExtension := &runtime.Unknown{
// Raw: originalPatchedObjJS,
// }
if err := info.Refresh(targetObj, true); err != nil {
return err
if didPatch {
if err := info.Refresh(targetObj, true); err != nil {
return err
}
}
return cmdutil.PrintObject(cmd, info.Object, out)
if len(options.OutputFormat) > 0 && options.OutputFormat != "name" {
return cmdutil.PrintObject(cmd, info.Object, out)
}
cmdutil.PrintSuccess(options.OutputFormat == "name", out, info.Object, options.DryRun, patchOperation(didPatch))
return nil
})
if err != nil {
return err
@ -282,3 +281,10 @@ func getPatchedJSON(patchType types.PatchType, originalJS, patchJS []byte, gvk s
return nil, fmt.Errorf("unknown Content-Type header for patch: %v", patchType)
}
}
func patchOperation(didPatch bool) string {
if didPatch {
return "patched"
}
return "not patched"
}