add ignored fields to apply
diff --git a/internal/fixture/state.go b/internal/fixture/state.go
index a055095..05caa9c 100644
--- a/internal/fixture/state.go
+++ b/internal/fixture/state.go
@@ -137,7 +137,7 @@
return s.UpdateObject(tv, version, ignored, manager)
}
-func (s *State) ApplyObject(tv *typed.TypedValue, version fieldpath.APIVersion, manager string, force bool) error {
+func (s *State) ApplyObject(tv *typed.TypedValue, version fieldpath.APIVersion, ignored *fieldpath.Set, manager string, force bool) error {
err := s.checkInit(version)
if err != nil {
return err
@@ -146,7 +146,7 @@
if err != nil {
return err
}
- new, managers, err := s.Updater.Apply(s.Live, tv, version, s.Managers, manager, force)
+ new, managers, err := s.Updater.Apply(s.Live, tv, version, s.Managers, ignored, manager, force)
if err != nil {
return err
}
@@ -158,12 +158,12 @@
}
// Apply the passed in object to the current state
-func (s *State) Apply(obj typed.YAMLObject, version fieldpath.APIVersion, manager string, force bool) error {
+func (s *State) Apply(obj typed.YAMLObject, version fieldpath.APIVersion, ignored *fieldpath.Set, manager string, force bool) error {
tv, err := s.Parser.Type(string(version)).FromYAML(FixTabsOrDie(obj))
if err != nil {
return err
}
- return s.ApplyObject(tv, version, manager, force)
+ return s.ApplyObject(tv, version, ignored, manager, force)
}
// CompareLive takes a YAML string and returns the comparison with the
@@ -231,10 +231,11 @@
// conflict, the user can specify the expected conflicts. If conflicts
// don't match, an error will occur.
type Apply struct {
- Manager string
- APIVersion fieldpath.APIVersion
- Object typed.YAMLObject
- Conflicts merge.Conflicts
+ Manager string
+ APIVersion fieldpath.APIVersion
+ Object typed.YAMLObject
+ Conflicts merge.Conflicts
+ IgnoredFields *fieldpath.Set
}
var _ Operation = &Apply{}
@@ -253,24 +254,26 @@
return nil, err
}
return ApplyObject{
- Manager: a.Manager,
- APIVersion: a.APIVersion,
- Object: tv,
- Conflicts: a.Conflicts,
+ Manager: a.Manager,
+ APIVersion: a.APIVersion,
+ Object: tv,
+ Conflicts: a.Conflicts,
+ IgnoredFields: a.IgnoredFields,
}, nil
}
type ApplyObject struct {
- Manager string
- APIVersion fieldpath.APIVersion
- Object *typed.TypedValue
- Conflicts merge.Conflicts
+ Manager string
+ APIVersion fieldpath.APIVersion
+ Object *typed.TypedValue
+ Conflicts merge.Conflicts
+ IgnoredFields *fieldpath.Set
}
var _ Operation = &ApplyObject{}
func (a ApplyObject) run(state *State) error {
- err := state.ApplyObject(a.Object, a.APIVersion, a.Manager, false)
+ err := state.ApplyObject(a.Object, a.APIVersion, a.IgnoredFields, a.Manager, false)
if err != nil {
if _, ok := err.(merge.Conflicts); !ok || a.Conflicts == nil {
return err
@@ -300,15 +303,16 @@
// ForceApply is a type of operation. It is a forced-apply run by a
// manager with a given object. Any error will be returned.
type ForceApply struct {
- Manager string
- APIVersion fieldpath.APIVersion
- Object typed.YAMLObject
+ Manager string
+ APIVersion fieldpath.APIVersion
+ Object typed.YAMLObject
+ IgnoredFields *fieldpath.Set
}
var _ Operation = &ForceApply{}
func (f ForceApply) run(state *State) error {
- return state.Apply(f.Object, f.APIVersion, f.Manager, true)
+ return state.Apply(f.Object, f.APIVersion, f.IgnoredFields, f.Manager, true)
}
func (f ForceApply) preprocess(parser Parser) (Operation, error) {
@@ -317,24 +321,26 @@
return nil, err
}
return ForceApplyObject{
- Manager: f.Manager,
- APIVersion: f.APIVersion,
- Object: tv,
+ Manager: f.Manager,
+ APIVersion: f.APIVersion,
+ Object: tv,
+ IgnoredFields: f.IgnoredFields,
}, nil
}
// ForceApplyObject is a type of operation. It is a forced-apply run by
// a manager with a given object. Any error will be returned.
type ForceApplyObject struct {
- Manager string
- APIVersion fieldpath.APIVersion
- Object *typed.TypedValue
+ Manager string
+ APIVersion fieldpath.APIVersion
+ Object *typed.TypedValue
+ IgnoredFields *fieldpath.Set
}
var _ Operation = &ForceApplyObject{}
func (f ForceApplyObject) run(state *State) error {
- return state.ApplyObject(f.Object, f.APIVersion, f.Manager, true)
+ return state.ApplyObject(f.Object, f.APIVersion, f.IgnoredFields, f.Manager, true)
}
func (f ForceApplyObject) preprocess(parser Parser) (Operation, error) {
@@ -567,6 +573,9 @@
}
return fmt.Errorf("manager not found: %s", op.Manager)
}
+ if op.Fields == nil {
+ op.Fields = fieldpath.NewSet()
+ }
if diff := manager.Set().Difference(op.Fields); !diff.Empty() {
return fmt.Errorf("unexpected managedFields for %s: \n%v", op.Manager, diff)
}
diff --git a/merge/ignore_test.go b/merge/ignore_test.go
index 1a93cf1..63401ac 100644
--- a/merge/ignore_test.go
+++ b/merge/ignore_test.go
@@ -9,7 +9,7 @@
func TestIgnoredFields(t *testing.T) {
tests := map[string]TestCase{
- "do_not_own_ignored": {
+ "update_does_not_own_ignored": {
APIVersion: "v1",
Ops: []Operation{
Update{
@@ -38,7 +38,7 @@
},
},
},
- "do_not_steal_ignored": {
+ "update_does_not_steal_ignored": {
APIVersion: "v1",
Ops: []Operation{
Update{
@@ -85,7 +85,7 @@
},
},
},
- "do_not_own_deep_ignored": {
+ "update_does_not_own_deep_ignored": {
APIVersion: "v1",
Ops: []Operation{
Update{
@@ -108,6 +108,114 @@
},
},
},
+ "apply_does_not_own_ignored": {
+ APIVersion: "v1",
+ Ops: []Operation{
+ Apply{
+ Manager: "default",
+ APIVersion: "v1",
+ Object: `
+ numeric: 1
+ string: "some string"
+ `,
+ IgnoredFields: fieldpath.NewSet(
+ fieldpath.MakePathOrDie("string"),
+ ),
+ },
+ ExpectState{
+ APIVersion: "v1",
+ Object: `
+ numeric: 1
+ string: "some string"
+ `,
+ },
+ ExpectManagedFields{
+ Manager: "default",
+ Fields: fieldpath.NewSet(
+ fieldpath.MakePathOrDie("numeric"),
+ ),
+ },
+ },
+ },
+ "apply_does_not_steal_ignored": {
+ APIVersion: "v1",
+ Ops: []Operation{
+ Apply{
+ Manager: "default",
+ APIVersion: "v1",
+ Object: `
+ numeric: 1
+ string: "some string"
+ `,
+ },
+ ExpectState{
+ APIVersion: "v1",
+ Object: `
+ numeric: 1
+ string: "some string"
+ `,
+ },
+ ExpectManagedFields{
+ Manager: "default",
+ Fields: fieldpath.NewSet(
+ fieldpath.MakePathOrDie("numeric"),
+ fieldpath.MakePathOrDie("string"),
+ ),
+ },
+ Apply{
+ Manager: "default2",
+ APIVersion: "v1",
+ Object: `
+ numeric: 1
+ string: "no string"
+ `,
+ IgnoredFields: fieldpath.NewSet(fieldpath.MakePathOrDie("string")),
+ },
+ ExpectState{
+ APIVersion: "v1",
+ Object: `
+ numeric: 1
+ string: "some string"
+ `,
+ },
+ ExpectManagedFields{
+ Manager: "default",
+ Fields: fieldpath.NewSet(
+ fieldpath.MakePathOrDie("numeric"),
+ fieldpath.MakePathOrDie("string"),
+ ),
+ },
+ ExpectManagedFields{
+ Manager: "default2",
+ Fields: fieldpath.NewSet(
+ fieldpath.MakePathOrDie("numeric"),
+ ),
+ },
+ },
+ },
+ "apply_does_not_own_deep_ignored": {
+ APIVersion: "v1",
+ Ops: []Operation{
+ Apply{
+ Manager: "default",
+ APIVersion: "v1",
+ Object: `{"numeric": 1, "obj": {"string": "foo", "numeric": 2}}`,
+ IgnoredFields: fieldpath.NewSet(
+ fieldpath.MakePathOrDie("obj"),
+ ),
+ },
+ ExpectState{
+ APIVersion: "v1",
+ Object: `{"numeric": 1, "obj": {"string": "foo", "numeric": 2}}`,
+ },
+ ExpectManagedFields{
+ Manager: "default",
+ Fields: fieldpath.NewSet(
+ fieldpath.MakePathOrDie("numeric"),
+ ),
+ },
+ },
+ },
}
for name, test := range tests {
diff --git a/merge/obsolete_versions_test.go b/merge/obsolete_versions_test.go
index 9498a9c..4ac2413 100644
--- a/merge/obsolete_versions_test.go
+++ b/merge/obsolete_versions_test.go
@@ -113,13 +113,13 @@
Parser: SameVersionParser{T: parser.Type("sets")},
}
- if err := state.Apply(typed.YAMLObject(`{"list": ["a", "b", "c", "d"]}`), fieldpath.APIVersion("v1"), "apply", false); err != nil {
+ if err := state.Apply(typed.YAMLObject(`{"list": ["a", "b", "c", "d"]}`), fieldpath.APIVersion("v1"), nil, "apply", false); err != nil {
t.Fatalf("Failed to apply: %v", err)
}
// Remove v1, add v2 instead.
converter.AcceptedVersions = []fieldpath.APIVersion{"v2"}
- if err := state.Apply(typed.YAMLObject(`{"list": ["a"]}`), fieldpath.APIVersion("v2"), "apply", false); err != nil {
+ if err := state.Apply(typed.YAMLObject(`{"list": ["a"]}`), fieldpath.APIVersion("v2"), nil, "apply", false); err != nil {
t.Fatalf("Failed to apply: %v", err)
}
diff --git a/merge/update.go b/merge/update.go
index e4815e5..4bd65a7 100644
--- a/merge/update.go
+++ b/merge/update.go
@@ -80,6 +80,7 @@
if err != nil {
return nil, nil, fmt.Errorf("failed to compare objects: %v", err)
}
+ compare.Remove(ignored)
versions[managerSet.APIVersion()] = compare
}
@@ -150,7 +151,7 @@
// well as the configuration that is applied. This will merge the object
// and return it. If the object hasn't changed, nil is returned (the
// managers can still have changed though).
-func (s *Updater) Apply(liveObject, configObject *typed.TypedValue, version fieldpath.APIVersion, managers fieldpath.ManagedFields, manager string, force bool) (*typed.TypedValue, fieldpath.ManagedFields, error) {
+func (s *Updater) Apply(liveObject, configObject *typed.TypedValue, version fieldpath.APIVersion, managers fieldpath.ManagedFields, ignored *fieldpath.Set, manager string, force bool) (*typed.TypedValue, fieldpath.ManagedFields, error) {
managers = shallowCopyManagers(managers)
var err error
if s.enableUnions {
@@ -171,6 +172,9 @@
}
lastSet := managers[manager]
set, err := configObject.ToFieldSet()
+ if ignored != nil {
+ set = set.RecursiveDifference(ignored)
+ }
if err != nil {
return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to get field set: %v", err)
}
@@ -179,7 +183,7 @@
if err != nil {
return nil, fieldpath.ManagedFields{}, fmt.Errorf("failed to prune fields: %v", err)
}
- managers, compare, err := s.update(liveObject, newObject, version, managers, nil, manager, force)
+ managers, compare, err := s.update(liveObject, newObject, version, managers, ignored, manager, force)
if err != nil {
return nil, fieldpath.ManagedFields{}, err
}