From b5d9fc0b182ff3d1a777dabec74314df3157edbb Mon Sep 17 00:00:00 2001 From: Florian Bacher Date: Wed, 18 Oct 2023 12:56:37 +0200 Subject: [PATCH] fix(lifecycle-operator): make sure the CloudEvents endpoint from the KeptnConfig is applied (#2289) Signed-off-by: Florian Bacher --- .../options/keptnconfig_controller.go | 17 ++- .../options/keptnconfig_controller_test.go | 118 +++++++++++------- lifecycle-operator/main.go | 12 +- 3 files changed, 95 insertions(+), 52 deletions(-) diff --git a/lifecycle-operator/controllers/options/keptnconfig_controller.go b/lifecycle-operator/controllers/options/keptnconfig_controller.go index b0a97ed80a..08677b4c0b 100644 --- a/lifecycle-operator/controllers/options/keptnconfig_controller.go +++ b/lifecycle-operator/controllers/options/keptnconfig_controller.go @@ -40,6 +40,17 @@ type KeptnConfigReconciler struct { Log logr.Logger LastAppliedSpec *optionsv1alpha1.KeptnConfigSpec DefaultCollectorURL string + config config.IConfig +} + +func NewReconciler(client client.Client, scheme *runtime.Scheme, log logr.Logger, collectorUrl string) *KeptnConfigReconciler { + return &KeptnConfigReconciler{ + Client: client, + Scheme: scheme, + Log: log, + config: config.Instance(), + DefaultCollectorURL: collectorUrl, + } } // +kubebuilder:rbac:groups=options.keptn.sh,resources=keptnconfigs,verbs=get;list;watch @@ -64,13 +75,13 @@ func (r *KeptnConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) r.initConfig() } + // reconcile config values + r.config.SetCreationRequestTimeout(time.Duration(cfg.Spec.KeptnAppCreationRequestTimeoutSeconds) * time.Second) + r.config.SetCloudEventsEndpoint(cfg.Spec.CloudEventsEndpoint) result, err := r.reconcileOtelCollectorUrl(cfg) if err != nil { return result, err } - // reconcile config values - cfgInstance := config.Instance() - cfgInstance.SetCreationRequestTimeout(time.Duration(cfg.Spec.KeptnAppCreationRequestTimeoutSeconds) * time.Second) r.LastAppliedSpec = &cfg.Spec return ctrl.Result{}, nil diff --git a/lifecycle-operator/controllers/options/keptnconfig_controller_test.go b/lifecycle-operator/controllers/options/keptnconfig_controller_test.go index 327d07efba..6b1c6c5832 100644 --- a/lifecycle-operator/controllers/options/keptnconfig_controller_test.go +++ b/lifecycle-operator/controllers/options/keptnconfig_controller_test.go @@ -8,7 +8,9 @@ import ( "github.com/go-logr/logr" optionsv1alpha1 "github.com/keptn/lifecycle-toolkit/lifecycle-operator/apis/options/v1alpha1" + fakeconfig "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/config/fake" "github.com/keptn/lifecycle-toolkit/lifecycle-operator/controllers/common/fake" + "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" @@ -18,8 +20,6 @@ import ( ) func TestKeptnConfigReconciler_Reconcile(t *testing.T) { - reconciler := setupReconciler() - // set up logger opts := zap.Options{ Development: true, @@ -31,11 +31,14 @@ func TestKeptnConfigReconciler_Reconcile(t *testing.T) { req ctrl.Request } tests := []struct { - name string - args args - lastAppliedConfig *optionsv1alpha1.KeptnConfigSpec - want ctrl.Result - wantErr bool + name string + args args + lastAppliedConfig *optionsv1alpha1.KeptnConfigSpec + reconcileConfig *optionsv1alpha1.KeptnConfig + want ctrl.Result + wantErr bool + wantCreationRequestTimeoutConfig time.Duration + wantCloudEventsEndpointConfig string }{ { name: "test 1", @@ -48,6 +51,15 @@ func TestKeptnConfigReconciler_Reconcile(t *testing.T) { }, }, }, + reconcileConfig: &optionsv1alpha1.KeptnConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "empty-config", + Namespace: "keptn-lifecycle-toolkit-system", + }, + Spec: optionsv1alpha1.KeptnConfigSpec{ + OTelCollectorUrl: "", + }, + }, lastAppliedConfig: &optionsv1alpha1.KeptnConfigSpec{}, want: ctrl.Result{}, wantErr: false, @@ -63,6 +75,15 @@ func TestKeptnConfigReconciler_Reconcile(t *testing.T) { }, }, }, + reconcileConfig: &optionsv1alpha1.KeptnConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "empty-config", + Namespace: "keptn-lifecycle-toolkit-system", + }, + Spec: optionsv1alpha1.KeptnConfigSpec{ + OTelCollectorUrl: "", + }, + }, want: ctrl.Result{}, wantErr: false, }, @@ -77,6 +98,15 @@ func TestKeptnConfigReconciler_Reconcile(t *testing.T) { }, }, }, + reconcileConfig: &optionsv1alpha1.KeptnConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "empty-config", + Namespace: "keptn-lifecycle-toolkit-system", + }, + Spec: optionsv1alpha1.KeptnConfigSpec{ + OTelCollectorUrl: "", + }, + }, want: ctrl.Result{}, wantErr: false, }, @@ -94,12 +124,26 @@ func TestKeptnConfigReconciler_Reconcile(t *testing.T) { lastAppliedConfig: &optionsv1alpha1.KeptnConfigSpec{ OTelCollectorUrl: "some-url", }, - want: ctrl.Result{Requeue: true, RequeueAfter: 10 * time.Second}, - wantErr: true, + reconcileConfig: &optionsv1alpha1.KeptnConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "config1", + Namespace: "keptn-lifecycle-toolkit-system", + }, + Spec: optionsv1alpha1.KeptnConfigSpec{ + OTelCollectorUrl: "url1", + KeptnAppCreationRequestTimeoutSeconds: 10, + CloudEventsEndpoint: "ce-endpoint", + }, + }, + want: ctrl.Result{Requeue: true, RequeueAfter: 10 * time.Second}, + wantCloudEventsEndpointConfig: "ce-endpoint", + wantCreationRequestTimeoutConfig: 10 * time.Second, + wantErr: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + reconciler := setupReconciler(tt.reconcileConfig) reconciler.LastAppliedSpec = tt.lastAppliedConfig got, err := reconciler.Reconcile(tt.args.ctx, tt.args.req) if (err != nil) != tt.wantErr { @@ -109,6 +153,17 @@ func TestKeptnConfigReconciler_Reconcile(t *testing.T) { if !reflect.DeepEqual(got, tt.want) { t.Errorf("Reconcile() got = %v, want %v", got, tt.want) } + + mockConfig := reconciler.config.(*fakeconfig.MockConfig) + + if tt.wantCreationRequestTimeoutConfig > 0 { + require.Len(t, mockConfig.SetCreationRequestTimeoutCalls(), 1) + require.Equal(t, tt.wantCreationRequestTimeoutConfig, mockConfig.SetCreationRequestTimeoutCalls()[0].Value) + } + if tt.wantCloudEventsEndpointConfig != "" { + require.Len(t, mockConfig.SetCloudEventsEndpointCalls(), 1) + require.Equal(t, tt.wantCloudEventsEndpointConfig, mockConfig.SetCloudEventsEndpointCalls()[0].Endpoint) + } }) } } @@ -233,47 +288,24 @@ func TestKeptnConfigReconciler_reconcileOtelCollectorUrl(t *testing.T) { } } -func setupReconciler() *KeptnConfigReconciler { - emptyConfig := &optionsv1alpha1.KeptnConfig{ - ObjectMeta: metav1.ObjectMeta{ - Name: "empty-config", - Namespace: "keptn-lifecycle-toolkit-system", - }, - Spec: optionsv1alpha1.KeptnConfigSpec{ - OTelCollectorUrl: "", - }, - } - config1 := &optionsv1alpha1.KeptnConfig{ - ObjectMeta: metav1.ObjectMeta{ - Name: "config1", - Namespace: "keptn-lifecycle-toolkit-system", - }, - Spec: optionsv1alpha1.KeptnConfigSpec{ - OTelCollectorUrl: "url1", - }, - } - config2 := &optionsv1alpha1.KeptnConfig{ - ObjectMeta: metav1.ObjectMeta{ - Name: "config2", - Namespace: "keptn-lifecycle-toolkit-system", - }, - Spec: optionsv1alpha1.KeptnConfigSpec{ - OTelCollectorUrl: "url2", - }, - } - +func setupReconciler(withConfig *optionsv1alpha1.KeptnConfig) *KeptnConfigReconciler { // setup logger opts := zap.Options{ Development: true, } ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - fakeClient := fake.NewClient(emptyConfig, config1, config2) + fakeClient := fake.NewClient(withConfig) - r := &KeptnConfigReconciler{ - Client: fakeClient, - Scheme: fakeClient.Scheme(), - Log: ctrl.Log.WithName("test-keptnconfig-controller"), + r := NewReconciler( + fakeClient, + fakeClient.Scheme(), + ctrl.Log.WithName("test-keptnconfig-controller"), + "", + ) + r.config = &fakeconfig.MockConfig{ + SetCloudEventsEndpointFunc: func(endpoint string) {}, + SetCreationRequestTimeoutFunc: func(value time.Duration) {}, } return r } diff --git a/lifecycle-operator/main.go b/lifecycle-operator/main.go index e2c5bcf151..7268749051 100644 --- a/lifecycle-operator/main.go +++ b/lifecycle-operator/main.go @@ -322,12 +322,12 @@ func main() { } configLogger := ctrl.Log.WithName("KeptnConfig Controller").V(env.KeptnOptionsControllerLogLevel) - configReconciler := &controlleroptions.KeptnConfigReconciler{ - Client: mgr.GetClient(), - Scheme: mgr.GetScheme(), - Log: configLogger, - DefaultCollectorURL: env.KeptnOptionsCollectorURL, - } + configReconciler := controlleroptions.NewReconciler( + mgr.GetClient(), + mgr.GetScheme(), + configLogger, + env.KeptnOptionsCollectorURL, + ) if err = (configReconciler).SetupWithManager(mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "KeptnConfig") os.Exit(1)