Add TrackableFilter interface (#4410)

* add kio filter interface

This interface is an extension of the Filter interface which can be used
for filters which are capable of tracking which fields they mutate.

* add TrackableSetter struct to filtersutil

This struct provides an abstraction to help Filters implement the
TrackableFilter interface

* implement TrackableFilter with annotations

This updates the annotations filter to implement the TrackableFilter
interface by reusing the TrackableSetter abstraction provided by
filtersutil.

This is done to provide a generic and consistent experience across the
filters

* implement TrackableFilter with labels

This updates the labels filter to implement the TrackableFilter
interface by reusing the TrackableSetter abstraction provided by
filtersutil.

This is done to provide a generic and consistent experience across the
filters
This commit is contained in:
sdowell
2022-01-24 11:05:32 -08:00
committed by GitHub
parent 69e5228264
commit 3687250ca2
6 changed files with 61 additions and 28 deletions

View File

@@ -20,22 +20,15 @@ type Filter struct {
// FsSlice contains the FieldSpecs to locate the namespace field
FsSlice types.FsSlice
// SetEntryCallback is invoked each time an annotation is applied
// Example use cases:
// - Tracking all paths where annotations have been applied
SetEntryCallback func(key, value, tag string, node *yaml.RNode)
trackableSetter filtersutil.TrackableSetter
}
var _ kio.Filter = Filter{}
var _ kio.TrackableFilter = &Filter{}
func (f Filter) setEntry(key, value, tag string) filtersutil.SetFn {
baseSetEntryFunc := filtersutil.SetEntry(key, value, tag)
return func(node *yaml.RNode) error {
if f.SetEntryCallback != nil {
f.SetEntryCallback(key, value, tag, node)
}
return baseSetEntryFunc(node)
}
// WithMutationTracker registers a callback which will be invoked each time a field is mutated
func (f *Filter) WithMutationTracker(callback func(key, value, tag string, node *yaml.RNode)) {
f.trackableSetter.WithMutationTracker(callback)
}
func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
@@ -45,7 +38,7 @@ func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
for _, k := range keys {
if err := node.PipeE(fsslice.Filter{
FsSlice: f.FsSlice,
SetValue: f.setEntry(
SetValue: f.trackableSetter.SetEntry(
k, f.Annotations[k], yaml.NodeTagString),
CreateKind: yaml.MappingNode, // Annotations are MappingNodes.
CreateTag: yaml.NodeTagMap,

View File

@@ -40,6 +40,7 @@ func TestAnnotations_Filter(t *testing.T) {
expectedOutput string
filter Filter
fsslice types.FsSlice
setEntryCallback func(key, value, tag string, node *yaml.RNode)
expectedSetEntryArgs []setEntryArg
}{
"add": {
@@ -259,8 +260,8 @@ spec:
"a": "a1",
"b": "b1",
},
SetEntryCallback: setEntryCallbackStub,
},
setEntryCallback: setEntryCallbackStub,
fsslice: []types.FieldSpec{
{
Path: "spec/template/metadata/annotations",
@@ -300,6 +301,7 @@ spec:
setEntryArgs = nil
t.Run(tn, func(t *testing.T) {
filter := tc.filter
filter.WithMutationTracker(tc.setEntryCallback)
filter.FsSlice = append(annosFs, tc.fsslice...)
if !assert.Equal(t,
strings.TrimSpace(tc.expectedOutput),