Add DesiredStateChanged to filter out updates going to status

Signed-off-by: Hasan Turken <turkenh@gmail.com>
This commit is contained in:
Hasan Turken 2023-01-23 16:45:29 +03:00
parent dae68b74df
commit c4ec21474a
No known key found for this signature in database
GPG Key ID: EE8BB9CB12F58415
2 changed files with 125 additions and 0 deletions

View File

@ -146,3 +146,17 @@ func IsNamed(name string) PredicateFn {
return mo.GetName() == name
}
}
// DesiredStateChanged accepts objects that have changed their desired state, i.e.
// the state that is not managed by the controller.
// To be more specific, it accepts update events that have changes in one of the followings:
// - `metadata.annotations`
// - `metadata.labels`
// - `spec`
func DesiredStateChanged() predicate.Predicate {
return predicate.Or(
predicate.AnnotationChangedPredicate{},
predicate.LabelChangedPredicate{},
predicate.GenerationChangedPredicate{},
)
}

View File

@ -24,7 +24,10 @@ import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
runtimev1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
"github.com/crossplane/crossplane-runtime/pkg/errors"
"github.com/crossplane/crossplane-runtime/pkg/meta"
"github.com/crossplane/crossplane-runtime/pkg/resource/fake"
@ -297,3 +300,111 @@ func TestIsNamed(t *testing.T) {
})
}
}
func TestDesiredStateChanged(t *testing.T) {
type args struct {
old client.Object
new client.Object
}
type want struct {
desiredStateChanged bool
}
cases := map[string]struct {
args
want
}{
"NothingChanged": {
args: args{
old: func() client.Object {
mg := &fake.Managed{}
return mg
}(),
new: func() client.Object {
mg := &fake.Managed{}
return mg
}(),
},
want: want{
desiredStateChanged: false,
},
},
"StatusChanged": {
args: args{
old: func() client.Object {
mg := &fake.Managed{}
return mg
}(),
new: func() client.Object {
mg := &fake.Managed{}
mg.SetConditions(runtimev1.ReconcileSuccess())
return mg
}(),
},
want: want{
desiredStateChanged: false,
},
},
"AnnotationsChanged": {
args: args{
old: func() client.Object {
mg := &fake.Managed{}
return mg
}(),
new: func() client.Object {
mg := &fake.Managed{}
mg.SetAnnotations(map[string]string{"foo": "bar"})
return mg
}(),
},
want: want{
desiredStateChanged: true,
},
},
"LabelsChanged": {
args: args{
old: func() client.Object {
mg := &fake.Managed{}
return mg
}(),
new: func() client.Object {
mg := &fake.Managed{}
mg.SetLabels(map[string]string{"foo": "bar"})
return mg
}(),
},
want: want{
desiredStateChanged: true,
},
},
// This happens when spec is changed.
"GenerationChanged": {
args: args{
old: func() client.Object {
mg := &fake.Managed{}
mg.SetGeneration(1)
return mg
}(),
new: func() client.Object {
mg := &fake.Managed{}
mg.SetGeneration(2)
return mg
}(),
},
want: want{
desiredStateChanged: true,
},
},
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
got := DesiredStateChanged().Update(event.UpdateEvent{
ObjectOld: tc.args.old,
ObjectNew: tc.args.new,
})
if diff := cmp.Diff(tc.want.desiredStateChanged, got); diff != "" {
t.Errorf("DesiredStateChanged(...): -want, +got:\n%s", diff)
}
})
}
}