Change kubectl diff to exclude managedFields by default
Changes kubectl diff to exclude managedFields by default. Adds a new --show-managed-fields flag that allows you to include managed fields in the diff.
This commit is contained in:
		@@ -106,6 +106,7 @@ type DiffOptions struct {
 | 
			
		||||
	ServerSideApply   bool
 | 
			
		||||
	FieldManager      string
 | 
			
		||||
	ForceConflicts    bool
 | 
			
		||||
	ShowManagedFields bool
 | 
			
		||||
 | 
			
		||||
	Selector         string
 | 
			
		||||
	OpenAPISchema    openapi.Resources
 | 
			
		||||
@@ -164,6 +165,7 @@ func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C
 | 
			
		||||
	usage := "contains the configuration to diff"
 | 
			
		||||
	cmd.Flags().StringArray("prune-allowlist", []string{}, "Overwrite the default whitelist with <group/version/kind> for --prune")
 | 
			
		||||
	cmd.Flags().Bool("prune", false, "Include resources that would be deleted by pruning. Can be used with -l and default shows all resources would be pruned")
 | 
			
		||||
	cmd.Flags().BoolVar(&options.ShowManagedFields, "show-managed-fields", options.ShowManagedFields, "If true, include managed fields in the diff.")
 | 
			
		||||
	cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
 | 
			
		||||
	cmdutil.AddServerSideApplyFlags(cmd)
 | 
			
		||||
	cmdutil.AddFieldManagerFlagVar(cmd, &options.FieldManager, apply.FieldManagerClientSideApply)
 | 
			
		||||
@@ -555,7 +557,7 @@ func NewDiffer(from, to string) (*Differ, error) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Diff diffs to versions of a specific object, and print both versions to directories.
 | 
			
		||||
func (d *Differ) Diff(obj Object, printer Printer) error {
 | 
			
		||||
func (d *Differ) Diff(obj Object, printer Printer, showManagedFields bool) error {
 | 
			
		||||
	from, err := d.From.getObject(obj)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
@@ -565,6 +567,11 @@ func (d *Differ) Diff(obj Object, printer Printer) error {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !showManagedFields {
 | 
			
		||||
		from = omitManagedFields(from)
 | 
			
		||||
		to = omitManagedFields(to)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Mask secret values if object is V1Secret
 | 
			
		||||
	if gvk := to.GetObjectKind().GroupVersionKind(); gvk.Version == "v1" && gvk.Kind == "Secret" {
 | 
			
		||||
		m, err := NewMasker(from, to)
 | 
			
		||||
@@ -583,6 +590,16 @@ func (d *Differ) Diff(obj Object, printer Printer) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func omitManagedFields(o runtime.Object) runtime.Object {
 | 
			
		||||
	a, err := meta.Accessor(o)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		// The object is not a `metav1.Object`, ignore it.
 | 
			
		||||
		return o
 | 
			
		||||
	}
 | 
			
		||||
	a.SetManagedFields(nil)
 | 
			
		||||
	return o
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Run runs the diff program against both directories.
 | 
			
		||||
func (d *Differ) Run(diff *DiffProgram) error {
 | 
			
		||||
	return diff.Run(d.From.Dir.Name, d.To.Dir.Name)
 | 
			
		||||
@@ -653,7 +670,7 @@ func (o *DiffOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RunDiff uses the factory to parse file arguments, find the version to
 | 
			
		||||
// Run uses the factory to parse file arguments, find the version to
 | 
			
		||||
// diff, and find each Info object for each files, and runs against the
 | 
			
		||||
// differ.
 | 
			
		||||
func (o *DiffOptions) Run() error {
 | 
			
		||||
@@ -718,7 +735,7 @@ func (o *DiffOptions) Run() error {
 | 
			
		||||
				o.pruner.MarkVisited(info)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			err = differ.Diff(obj, printer)
 | 
			
		||||
			err = differ.Diff(obj, printer, o.ShowManagedFields)
 | 
			
		||||
			if !isConflict(err) {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ package diff
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/ioutil"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
@@ -200,7 +201,7 @@ func TestDiffer(t *testing.T) {
 | 
			
		||||
		live:   map[string]interface{}{"live": true},
 | 
			
		||||
		merged: map[string]interface{}{"merged": true},
 | 
			
		||||
	}
 | 
			
		||||
	err = diff.Diff(&obj, Printer{})
 | 
			
		||||
	err = diff.Diff(&obj, Printer{}, true)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
@@ -223,6 +224,85 @@ func TestDiffer(t *testing.T) {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestShowManagedFields(t *testing.T) {
 | 
			
		||||
	diff, err := NewDiffer("LIVE", "MERGED")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
	defer diff.TearDown()
 | 
			
		||||
 | 
			
		||||
	testCases := []struct {
 | 
			
		||||
		name                string
 | 
			
		||||
		showManagedFields   bool
 | 
			
		||||
		expectedFromContent string
 | 
			
		||||
		expectedToContent   string
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name:              "without managed fields",
 | 
			
		||||
			showManagedFields: false,
 | 
			
		||||
			expectedFromContent: `live: true
 | 
			
		||||
metadata:
 | 
			
		||||
  name: foo
 | 
			
		||||
`,
 | 
			
		||||
			expectedToContent: `merged: true
 | 
			
		||||
metadata:
 | 
			
		||||
  name: foo
 | 
			
		||||
`,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:              "with managed fields",
 | 
			
		||||
			showManagedFields: true,
 | 
			
		||||
			expectedFromContent: `live: true
 | 
			
		||||
metadata:
 | 
			
		||||
  managedFields: mf-data
 | 
			
		||||
  name: foo
 | 
			
		||||
`,
 | 
			
		||||
			expectedToContent: `merged: true
 | 
			
		||||
metadata:
 | 
			
		||||
  managedFields: mf-data
 | 
			
		||||
  name: foo
 | 
			
		||||
`,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, tc := range testCases {
 | 
			
		||||
		t.Run(tc.name, func(t *testing.T) {
 | 
			
		||||
			obj := FakeObject{
 | 
			
		||||
				name: fmt.Sprintf("TestCase%d", i),
 | 
			
		||||
				live: map[string]interface{}{
 | 
			
		||||
					"live": true,
 | 
			
		||||
					"metadata": map[string]interface{}{
 | 
			
		||||
						"managedFields": "mf-data",
 | 
			
		||||
						"name":          "foo",
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
				merged: map[string]interface{}{
 | 
			
		||||
					"merged": true,
 | 
			
		||||
					"metadata": map[string]interface{}{
 | 
			
		||||
						"managedFields": "mf-data",
 | 
			
		||||
						"name":          "foo",
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			err = diff.Diff(&obj, Printer{}, tc.showManagedFields)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				t.Fatal(err)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			actualFromContent, _ := ioutil.ReadFile(path.Join(diff.From.Dir.Name, obj.Name()))
 | 
			
		||||
			if string(actualFromContent) != tc.expectedFromContent {
 | 
			
		||||
				t.Fatalf("File has %q, expected %q", string(actualFromContent), tc.expectedFromContent)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			actualToContent, _ := ioutil.ReadFile(path.Join(diff.To.Dir.Name, obj.Name()))
 | 
			
		||||
			if string(actualToContent) != tc.expectedToContent {
 | 
			
		||||
				t.Fatalf("File has %q, expected %q", string(actualToContent), tc.expectedToContent)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestMasker(t *testing.T) {
 | 
			
		||||
	type diff struct {
 | 
			
		||||
		from runtime.Object
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user