From 1733359cb4c3662151f35e633b3b1cd1b6640c53 Mon Sep 17 00:00:00 2001 From: Jim Fitzpatrick Date: Wed, 25 Sep 2024 13:48:58 +0100 Subject: [PATCH] Improve the getting of the kuadrant CR. Get the oldest kuadrant CR and use that as the only CR. Signed-off-by: Jim Fitzpatrick --- controllers/state_of_the_world.go | 37 ++++- controllers/state_of_the_world_test.go | 178 +++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 7 deletions(-) create mode 100644 controllers/state_of_the_world_test.go diff --git a/controllers/state_of_the_world.go b/controllers/state_of_the_world.go index 51868530d..0a8a07a4c 100644 --- a/controllers/state_of_the_world.go +++ b/controllers/state_of_the_world.go @@ -114,14 +114,11 @@ func (r *AuthorinoCrReconciler) Reconcile(ctx context.Context, _ []controller.Re } return nil, false }) - if len(kobjs) == 0 { - logger.Info("no kuadrant resources found", "status", "skipping") - return - } - if len(kobjs) > 1 { - logger.Error(fmt.Errorf("multiple Kuadrant resources found"), "cannot select root Kuadrant resource", "status", "error") + + kobj, err := GetOldestKuadrant(kobjs) + if err != nil { + logger.Error(err, "cannot find Kuadrant resource", "status", "error") } - kobj := kobjs[0] if kobj.GetDeletionTimestamp() != nil { logger.Info("root kuadrant marked for deletion", "status", "skipping") @@ -280,3 +277,29 @@ func (e *EventLogger) Log(ctx context.Context, resourceEvents []controller.Resou } } } + +func GetOldestKuadrant(kuadrants []*kuadrantv1beta1.Kuadrant) (*kuadrantv1beta1.Kuadrant, error) { + if len(kuadrants) == 1 { + return kuadrants[0], nil + } + if len(kuadrants) == 0 { + return nil, fmt.Errorf("empty list passed") + } + oldest := kuadrants[0] + for _, k := range kuadrants[1:] { + if k == nil || k.DeletionTimestamp != nil { + continue + } + if oldest == nil { + oldest = k + continue + } + if k.CreationTimestamp.Before(&oldest.CreationTimestamp) { + oldest = k + } + } + if oldest == nil { + return nil, fmt.Errorf("only nil pointers in list") + } + return oldest, nil +} diff --git a/controllers/state_of_the_world_test.go b/controllers/state_of_the_world_test.go new file mode 100644 index 000000000..9149e05be --- /dev/null +++ b/controllers/state_of_the_world_test.go @@ -0,0 +1,178 @@ +package controllers + +import ( + "reflect" + "testing" + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" +) + +func TestGetOldest(t *testing.T) { + type args struct { + kuadrants []*kuadrantv1beta1.Kuadrant + } + tests := []struct { + name string + args args + want *kuadrantv1beta1.Kuadrant + wantErr bool + }{ + { + name: "oldest is first", + args: args{ + kuadrants: []*kuadrantv1beta1.Kuadrant{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "Expected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(1, 0), + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "UnExpected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(2, 0), + }, + }, + }, + }, + }, + want: &kuadrantv1beta1.Kuadrant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "Expected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(1, 0), + }, + }, + }, + wantErr: false, + }, + { + name: "oldest is second", + args: args{ + kuadrants: []*kuadrantv1beta1.Kuadrant{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "UnExpected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(2, 0), + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "Expected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(1, 0), + }, + }, + }, + }, + }, + want: &kuadrantv1beta1.Kuadrant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "Expected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(1, 0), + }, + }, + }, + wantErr: false, + }, + { + name: "Empty list is passed", + args: args{kuadrants: []*kuadrantv1beta1.Kuadrant{}}, + want: nil, + wantErr: true, + }, + { + name: "List contains nil pointer", + args: args{ + kuadrants: []*kuadrantv1beta1.Kuadrant{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "UnExpected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(2, 0), + }, + }, + }, + nil, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "Expected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(1, 0), + }, + }, + }, + }, + }, + want: &kuadrantv1beta1.Kuadrant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "Expected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(1, 0), + }, + }, + }, + wantErr: false, + }, + { + name: "first object is nil pointer", + args: args{ + kuadrants: []*kuadrantv1beta1.Kuadrant{ + nil, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "UnExpected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(2, 0), + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "Expected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(1, 0), + }, + }, + }, + }, + }, + want: &kuadrantv1beta1.Kuadrant{ + ObjectMeta: metav1.ObjectMeta{ + Name: "Expected", + CreationTimestamp: metav1.Time{ + Time: time.Unix(1, 0), + }, + }, + }, + wantErr: false, + }, + { + name: "List contains all nil pointer", + args: args{[]*kuadrantv1beta1.Kuadrant{nil, nil, nil}}, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetOldestKuadrant(tt.args.kuadrants) + if (err != nil) != tt.wantErr { + t.Errorf("GetOldestKuadrant() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("GetOldestKuadrant() got = %v, want %v", got, tt.want) + } + }) + } +}