Merge pull request #111319 from brianpursley/kubectl-1242

Change kubectl diff to exclude managedFields by default
This commit is contained in:
Kubernetes Prow Robot 2022-07-27 19:27:10 -07:00 committed by GitHub
commit 1df7b3bed3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 104 additions and 7 deletions

View File

@ -103,9 +103,10 @@ func diffError(err error) exec.ExitError {
type DiffOptions struct {
FilenameOptions resource.FilenameOptions
ServerSideApply bool
FieldManager string
ForceConflicts bool
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
}

View File

@ -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