From d7980f0cd99436fc8649f119e6af147fb9332da8 Mon Sep 17 00:00:00 2001 From: Mike Rostermund Date: Mon, 12 Aug 2024 11:51:37 +0200 Subject: [PATCH 1/7] Improve mock for concurrent usage and remove entity ID annotation --- controllers/humioaction_annotations.go | 34 - controllers/humioaction_controller.go | 23 +- .../humioaggregatealert_annotations.go | 42 - controllers/humioaggregatealert_controller.go | 13 +- controllers/humioalert_annotations.go | 42 - controllers/humioalert_controller.go | 19 +- controllers/humiofilteralert_annotations.go | 42 - controllers/humiofilteralert_controller.go | 20 +- controllers/humioingesttoken_controller.go | 28 +- controllers/humioparser_controller.go | 4 +- controllers/humiorepository_controller.go | 23 +- .../humioscheduledsearch_annotations.go | 42 - .../humioscheduledsearch_controller.go | 19 +- controllers/humioview_controller.go | 55 +- .../clusters/humiocluster_controller_test.go | 108 +-- controllers/suite/clusters/suite_test.go | 46 +- .../humioresources_controller_test.go | 68 +- controllers/suite/resources/suite_test.go | 2 +- go.mod | 2 +- go.sum | 4 +- pkg/humio/action_transform.go | 5 - pkg/humio/aggregatealert_transform.go | 45 +- pkg/humio/alert_transform.go | 23 +- pkg/humio/client.go | 69 +- pkg/humio/client_mock.go | 784 ++++++++++++++---- pkg/humio/filteralert_transform.go | 23 +- pkg/humio/ingesttoken_transform.go | 15 + pkg/humio/parser_transform.go | 26 + pkg/humio/scheduledsearch_transform.go | 23 +- 29 files changed, 890 insertions(+), 759 deletions(-) delete mode 100644 controllers/humioaction_annotations.go delete mode 100644 controllers/humioaggregatealert_annotations.go delete mode 100644 controllers/humioalert_annotations.go delete mode 100644 controllers/humiofilteralert_annotations.go delete mode 100644 controllers/humioscheduledsearch_annotations.go create mode 100644 pkg/humio/ingesttoken_transform.go create mode 100644 pkg/humio/parser_transform.go diff --git a/controllers/humioaction_annotations.go b/controllers/humioaction_annotations.go deleted file mode 100644 index 3fd0b198..00000000 --- a/controllers/humioaction_annotations.go +++ /dev/null @@ -1,34 +0,0 @@ -package controllers - -import ( - "context" - "fmt" - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func (r *HumioActionReconciler) reconcileHumioActionAnnotations(ctx context.Context, addedAction *humioapi.Action, ha *humiov1alpha1.HumioAction, req ctrl.Request) (reconcile.Result, error) { - r.Log.Info(fmt.Sprintf("Adding ID %s to action %s", addedAction.ID, addedAction.Name)) - actionCR := &humiov1alpha1.HumioAction{} - err := r.Get(ctx, req.NamespacedName, actionCR) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to add ID annotation to action") - } - - if len(actionCR.ObjectMeta.Annotations) < 1 { - actionCR.ObjectMeta.Annotations = make(map[string]string) - } - - actionCR.ObjectMeta.Annotations[humio.ActionIdentifierAnnotation] = addedAction.ID - - err = r.Update(ctx, actionCR) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to add ID annotation to action") - } - - r.Log.Info("Added ID to Action", "Action", ha.Spec.Name) - return reconcile.Result{}, nil -} diff --git a/controllers/humioaction_controller.go b/controllers/humioaction_controller.go index 49f38d73..eca81448 100644 --- a/controllers/humioaction_controller.go +++ b/controllers/humioaction_controller.go @@ -87,22 +87,22 @@ func (r *HumioActionReconciler) Reconcile(ctx context.Context, req ctrl.Request) return reconcile.Result{}, r.logErrorAndReturn(err, "could not resolve secret references") } - if _, err := humio.ActionFromActionCR(ha); err != nil { - r.Log.Error(err, "unable to validate action") - err = r.setState(ctx, humiov1alpha1.HumioActionStateConfigError, ha) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "unable to set action state") + if _, validateErr := humio.ActionFromActionCR(ha); validateErr != nil { + r.Log.Error(validateErr, "unable to validate action") + setStateErr := r.setState(ctx, humiov1alpha1.HumioActionStateConfigError, ha) + if setStateErr != nil { + return reconcile.Result{}, r.logErrorAndReturn(setStateErr, "unable to set action state") } - return reconcile.Result{}, err + return reconcile.Result{}, validateErr } defer func(ctx context.Context, humioClient humio.Client, ha *humiov1alpha1.HumioAction) { - curAction, err := r.HumioClient.GetAction(cluster.Config(), req, ha) + _, err := r.HumioClient.GetAction(cluster.Config(), req, ha) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioActionStateNotFound, ha) return } - if err != nil || curAction == nil { + if err != nil { _ = r.setState(ctx, humiov1alpha1.HumioActionStateUnknown, ha) return } @@ -160,12 +160,7 @@ func (r *HumioActionReconciler) reconcileHumioAction(ctx context.Context, config if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not create action") } - r.Log.Info("Created action", "Action", ha.Spec.Name) - - result, err := r.reconcileHumioActionAnnotations(ctx, addedAction, ha, req) - if err != nil { - return result, err - } + r.Log.Info("Created action", "Action", ha.Spec.Name, "ID", addedAction.ID) return reconcile.Result{Requeue: true}, nil } if err != nil { diff --git a/controllers/humioaggregatealert_annotations.go b/controllers/humioaggregatealert_annotations.go deleted file mode 100644 index 951e300d..00000000 --- a/controllers/humioaggregatealert_annotations.go +++ /dev/null @@ -1,42 +0,0 @@ -package controllers - -import ( - "context" - "fmt" - - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func (r *HumioAggregateAlertReconciler) reconcileHumioAggregateAlertAnnotations(ctx context.Context, addedAggregateAlert *humioapi.AggregateAlert, haa *humiov1alpha1.HumioAggregateAlert, req ctrl.Request) (reconcile.Result, error) { - r.Log.Info(fmt.Sprintf("Adding annotations to aggregate alert %q", addedAggregateAlert.Name)) - currentAggregateAlert := &humiov1alpha1.HumioAggregateAlert{} - err := r.Get(ctx, req.NamespacedName, currentAggregateAlert) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to add annotations to aggregate alert") - } - - // Copy annotations from the aggregate alerts transformer to get the current aggregate alert annotations - hydratedHumioAggregateAlert := &humiov1alpha1.HumioAggregateAlert{} - if err = humio.AggregateAlertHydrate(hydratedHumioAggregateAlert, addedAggregateAlert); err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to hydrate alert") - } - - if len(currentAggregateAlert.ObjectMeta.Annotations) < 1 { - currentAggregateAlert.ObjectMeta.Annotations = make(map[string]string) - } - for k, v := range hydratedHumioAggregateAlert.Annotations { - currentAggregateAlert.ObjectMeta.Annotations[k] = v - } - - err = r.Update(ctx, currentAggregateAlert) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to add annotations to aggregate alert") - } - - r.Log.Info("Added annotations to AggregateAlert", "AggregateAlert", haa.Spec.Name) - return reconcile.Result{}, nil -} diff --git a/controllers/humioaggregatealert_controller.go b/controllers/humioaggregatealert_controller.go index cbf38319..9f73c578 100644 --- a/controllers/humioaggregatealert_controller.go +++ b/controllers/humioaggregatealert_controller.go @@ -156,12 +156,7 @@ func (r *HumioAggregateAlertReconciler) reconcileHumioAggregateAlert(ctx context if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not create aggregate alert") } - r.Log.Info("Created aggregate alert", "AggregateAlert", haa.Spec.Name) - - result, err := r.reconcileHumioAggregateAlertAnnotations(ctx, addedAggregateAlert, haa, req) - if err != nil { - return result, err - } + r.Log.Info("Created aggregate alert", "AggregateAlert", haa.Spec.Name, "ID", addedAggregateAlert.ID) return reconcile.Result{Requeue: true}, nil } if err != nil { @@ -173,11 +168,7 @@ func (r *HumioAggregateAlertReconciler) reconcileHumioAggregateAlert(ctx context if err := r.HumioClient.ValidateActionsForAggregateAlert(config, req, haa); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not validate actions for aggregate alert") } - expectedAggregateAlert, err := humio.AggregateAlertTransform(haa) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not parse expected AggregateAlert") - } - + expectedAggregateAlert := humio.AggregateAlertTransform(haa) sanitizeAggregateAlert(curAggregateAlert) if !reflect.DeepEqual(*curAggregateAlert, *expectedAggregateAlert) { r.Log.Info(fmt.Sprintf("AggregateAlert differs, triggering update, expected %#v, got: %#v", diff --git a/controllers/humioalert_annotations.go b/controllers/humioalert_annotations.go deleted file mode 100644 index fa450457..00000000 --- a/controllers/humioalert_annotations.go +++ /dev/null @@ -1,42 +0,0 @@ -package controllers - -import ( - "context" - "fmt" - - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func (r *HumioAlertReconciler) reconcileHumioAlertAnnotations(ctx context.Context, addedAlert *humioapi.Alert, ha *humiov1alpha1.HumioAlert, req ctrl.Request) (reconcile.Result, error) { - r.Log.Info(fmt.Sprintf("Adding ID %q to alert %q", addedAlert.ID, addedAlert.Name)) - currentAlert := &humiov1alpha1.HumioAlert{} - err := r.Get(ctx, req.NamespacedName, currentAlert) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to add ID annotation to alert") - } - - // Copy annotations from the alerts transformer to get the current alert ID - hydratedHumioAlert := &humiov1alpha1.HumioAlert{} - if err = humio.AlertHydrate(hydratedHumioAlert, addedAlert, map[string]string{}); err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to hydrate alert") - } - - if len(currentAlert.ObjectMeta.Annotations) < 1 { - currentAlert.ObjectMeta.Annotations = make(map[string]string) - } - for k, v := range hydratedHumioAlert.Annotations { - currentAlert.ObjectMeta.Annotations[k] = v - } - - err = r.Update(ctx, currentAlert) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to add ID annotation to alert") - } - - r.Log.Info("Added id to Alert", "Alert", ha.Spec.Name) - return reconcile.Result{}, nil -} diff --git a/controllers/humioalert_controller.go b/controllers/humioalert_controller.go index 8fe8eaf6..e772f31a 100644 --- a/controllers/humioalert_controller.go +++ b/controllers/humioalert_controller.go @@ -86,13 +86,13 @@ func (r *HumioAlertReconciler) Reconcile(ctx context.Context, req ctrl.Request) } defer func(ctx context.Context, humioClient humio.Client, ha *humiov1alpha1.HumioAlert) { - curAlert, err := r.HumioClient.GetAlert(cluster.Config(), req, ha) + _, err := r.HumioClient.GetAlert(cluster.Config(), req, ha) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioAlertStateNotFound, ha) return } - if err != nil || curAlert == nil { - _ = r.setState(ctx, humiov1alpha1.HumioAlertStateConfigError, ha) + if err != nil { + _ = r.setState(ctx, humiov1alpha1.HumioAlertStateUnknown, ha) return } _ = r.setState(ctx, humiov1alpha1.HumioAlertStateExists, ha) @@ -149,12 +149,7 @@ func (r *HumioAlertReconciler) reconcileHumioAlert(ctx context.Context, config * if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not create alert") } - r.Log.Info("Created alert", "Alert", ha.Spec.Name) - - result, err := r.reconcileHumioAlertAnnotations(ctx, addedAlert, ha, req) - if err != nil { - return result, err - } + r.Log.Info("Created alert", "Alert", ha.Spec.Name, "ID", addedAlert.ID) return reconcile.Result{Requeue: true}, nil } if err != nil { @@ -167,11 +162,7 @@ func (r *HumioAlertReconciler) reconcileHumioAlert(ctx context.Context, config * if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not get action id mapping") } - expectedAlert, err := humio.AlertTransform(ha, actionIdMap) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not parse expected Alert") - } - + expectedAlert := humio.AlertTransform(ha, actionIdMap) sanitizeAlert(curAlert) if !reflect.DeepEqual(*curAlert, *expectedAlert) { r.Log.Info(fmt.Sprintf("Alert differs, triggering update, expected %#v, got: %#v", diff --git a/controllers/humiofilteralert_annotations.go b/controllers/humiofilteralert_annotations.go deleted file mode 100644 index dcc03668..00000000 --- a/controllers/humiofilteralert_annotations.go +++ /dev/null @@ -1,42 +0,0 @@ -package controllers - -import ( - "context" - "fmt" - - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func (r *HumioFilterAlertReconciler) reconcileHumioFilterAlertAnnotations(ctx context.Context, addedFilterAlert *humioapi.FilterAlert, hfa *humiov1alpha1.HumioFilterAlert, req ctrl.Request) (reconcile.Result, error) { - r.Log.Info(fmt.Sprintf("Adding annotations to filter alert %q", addedFilterAlert.Name)) - currentFilterAlert := &humiov1alpha1.HumioFilterAlert{} - err := r.Get(ctx, req.NamespacedName, currentFilterAlert) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to add annotations to filter alert") - } - - // Copy annotations from the filter alerts transformer to get the current filter alert annotations - hydratedHumioFilterAlert := &humiov1alpha1.HumioFilterAlert{} - if err = humio.FilterAlertHydrate(hydratedHumioFilterAlert, addedFilterAlert); err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to hydrate alert") - } - - if len(currentFilterAlert.ObjectMeta.Annotations) < 1 { - currentFilterAlert.ObjectMeta.Annotations = make(map[string]string) - } - for k, v := range hydratedHumioFilterAlert.Annotations { - currentFilterAlert.ObjectMeta.Annotations[k] = v - } - - err = r.Update(ctx, currentFilterAlert) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to add annotations to filter alert") - } - - r.Log.Info("Added annotations to FilterAlert", "FilterAlert", hfa.Spec.Name) - return reconcile.Result{}, nil -} diff --git a/controllers/humiofilteralert_controller.go b/controllers/humiofilteralert_controller.go index 09dcfa5f..d620b438 100644 --- a/controllers/humiofilteralert_controller.go +++ b/controllers/humiofilteralert_controller.go @@ -87,13 +87,13 @@ func (r *HumioFilterAlertReconciler) Reconcile(ctx context.Context, req ctrl.Req } defer func(ctx context.Context, humioClient humio.Client, hfa *humiov1alpha1.HumioFilterAlert) { - curFilterAlert, err := r.HumioClient.GetFilterAlert(cluster.Config(), req, hfa) + _, err := r.HumioClient.GetFilterAlert(cluster.Config(), req, hfa) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioFilterAlertStateNotFound, hfa) return } - if err != nil || curFilterAlert == nil { - _ = r.setState(ctx, humiov1alpha1.HumioFilterAlertStateConfigError, hfa) + if err != nil { + _ = r.setState(ctx, humiov1alpha1.HumioFilterAlertStateUnknown, hfa) return } _ = r.setState(ctx, humiov1alpha1.HumioFilterAlertStateExists, hfa) @@ -157,12 +157,7 @@ func (r *HumioFilterAlertReconciler) reconcileHumioFilterAlert(ctx context.Conte if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not create filter alert") } - r.Log.Info("Created filter alert", "FilterAlert", hfa.Spec.Name) - - result, err := r.reconcileHumioFilterAlertAnnotations(ctx, addedFilterAlert, hfa, req) - if err != nil { - return result, err - } + r.Log.Info("Created filter alert", "FilterAlert", hfa.Spec.Name, "ID", addedFilterAlert.ID) return reconcile.Result{Requeue: true}, nil } if err != nil { @@ -173,11 +168,7 @@ func (r *HumioFilterAlertReconciler) reconcileHumioFilterAlert(ctx context.Conte if err := r.HumioClient.ValidateActionsForFilterAlert(config, req, hfa); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not get action id mapping") } - expectedFilterAlert, err := humio.FilterAlertTransform(hfa) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not parse expected FilterAlert") - } - + expectedFilterAlert := humio.FilterAlertTransform(hfa) sanitizeFilterAlert(curFilterAlert) if !reflect.DeepEqual(*curFilterAlert, *expectedFilterAlert) { r.Log.Info(fmt.Sprintf("FilterAlert differs, triggering update, expected %#v, got: %#v", @@ -218,5 +209,6 @@ func (r *HumioFilterAlertReconciler) logErrorAndReturn(err error, msg string) er } func sanitizeFilterAlert(filterAlert *humioapi.FilterAlert) { + filterAlert.ID = "" filterAlert.RunAsUserID = "" } diff --git a/controllers/humioingesttoken_controller.go b/controllers/humioingesttoken_controller.go index 7e399e76..f27b9f7d 100644 --- a/controllers/humioingesttoken_controller.go +++ b/controllers/humioingesttoken_controller.go @@ -18,6 +18,7 @@ package controllers import ( "context" + "errors" "fmt" "github.com/go-logr/logr" humioapi "github.com/humio/cli/api" @@ -122,30 +123,22 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req } defer func(ctx context.Context, humioClient humio.Client, hit *humiov1alpha1.HumioIngestToken) { - curToken, err := humioClient.GetIngestToken(cluster.Config(), req, hit) - if err != nil { - _ = r.setState(ctx, humiov1alpha1.HumioIngestTokenStateUnknown, hit) + _, err := humioClient.GetIngestToken(cluster.Config(), req, hit) + if errors.As(err, &humioapi.EntityNotFound{}) { + _ = r.setState(ctx, humiov1alpha1.HumioIngestTokenStateNotFound, hit) return } - emptyToken := humioapi.IngestToken{} - if emptyToken != *curToken { - _ = r.setState(ctx, humiov1alpha1.HumioIngestTokenStateExists, hit) + if err != nil { + _ = r.setState(ctx, humiov1alpha1.HumioIngestTokenStateUnknown, hit) return } - _ = r.setState(ctx, humiov1alpha1.HumioIngestTokenStateNotFound, hit) + _ = r.setState(ctx, humiov1alpha1.HumioIngestTokenStateExists, hit) }(ctx, r.HumioClient, hit) // Get current ingest token r.Log.Info("get current ingest token") curToken, err := r.HumioClient.GetIngestToken(cluster.Config(), req, hit) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if ingest token exists") - } - // If token doesn't exist, the Get returns: nil, err. - // How do we distinguish between "doesn't exist" and "error while executing get"? - // TODO: change the way we do errors from the API so we can get rid of this hack - emptyToken := humioapi.IngestToken{} - if emptyToken == *curToken { + if errors.As(err, &humioapi.EntityNotFound{}) { r.Log.Info("ingest token doesn't exist. Now adding ingest token") // create token _, err := r.HumioClient.AddIngestToken(cluster.Config(), req, hit) @@ -155,6 +148,9 @@ func (r *HumioIngestTokenReconciler) Reconcile(ctx context.Context, req ctrl.Req r.Log.Info("created ingest token") return reconcile.Result{Requeue: true}, nil } + if err != nil { + return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if ingest token exists") + } // Trigger update if parser name changed if curToken.AssignedParser != hit.Spec.ParserName { @@ -243,7 +239,7 @@ func (r *HumioIngestTokenReconciler) ensureTokenSecretExists(ctx context.Context if string(existingSecret.Data["token"]) != string(desiredSecret.Data["token"]) { r.Log.Info("secret does not match the token in Humio. Updating token", "TokenSecretName", hit.Spec.TokenSecretName) if err = r.Update(ctx, desiredSecret); err != nil { - return r.logErrorAndReturn(err, "unable to update alert") + return r.logErrorAndReturn(err, "unable to update ingest token") } } } diff --git a/controllers/humioparser_controller.go b/controllers/humioparser_controller.go index af07b063..14d15799 100644 --- a/controllers/humioparser_controller.go +++ b/controllers/humioparser_controller.go @@ -123,12 +123,12 @@ func (r *HumioParserReconciler) Reconcile(ctx context.Context, req ctrl.Request) } defer func(ctx context.Context, humioClient humio.Client, hp *humiov1alpha1.HumioParser) { - curParser, err := humioClient.GetParser(cluster.Config(), req, hp) + _, err := humioClient.GetParser(cluster.Config(), req, hp) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioParserStateNotFound, hp) return } - if err != nil || curParser == nil { + if err != nil { _ = r.setState(ctx, humiov1alpha1.HumioParserStateUnknown, hp) return } diff --git a/controllers/humiorepository_controller.go b/controllers/humiorepository_controller.go index bbb77660..ff4238e8 100644 --- a/controllers/humiorepository_controller.go +++ b/controllers/humiorepository_controller.go @@ -18,8 +18,8 @@ package controllers import ( "context" + "errors" "fmt" - "reflect" "time" humioapi "github.com/humio/cli/api" @@ -121,14 +121,13 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ } defer func(ctx context.Context, humioClient humio.Client, hr *humiov1alpha1.HumioRepository) { - curRepository, err := humioClient.GetRepository(cluster.Config(), req, hr) - if err != nil { - _ = r.setState(ctx, humiov1alpha1.HumioRepositoryStateUnknown, hr) + _, err := humioClient.GetRepository(cluster.Config(), req, hr) + if errors.As(err, &humioapi.EntityNotFound{}) { + _ = r.setState(ctx, humiov1alpha1.HumioRepositoryStateNotFound, hr) return } - emptyRepository := humioapi.Parser{} - if reflect.DeepEqual(emptyRepository, *curRepository) { - _ = r.setState(ctx, humiov1alpha1.HumioRepositoryStateNotFound, hr) + if err != nil { + _ = r.setState(ctx, humiov1alpha1.HumioRepositoryStateUnknown, hr) return } _ = r.setState(ctx, humiov1alpha1.HumioRepositoryStateExists, hr) @@ -137,12 +136,7 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ // Get current repository r.Log.Info("get current repository") curRepository, err := r.HumioClient.GetRepository(cluster.Config(), req, hr) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if repository exists") - } - - emptyRepository := humioapi.Repository{} - if reflect.DeepEqual(emptyRepository, *curRepository) { + if errors.As(err, &humioapi.EntityNotFound{}) { r.Log.Info("repository doesn't exist. Now adding repository") // create repository _, err := r.HumioClient.AddRepository(cluster.Config(), req, hr) @@ -152,6 +146,9 @@ func (r *HumioRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Requ r.Log.Info("created repository", "RepositoryName", hr.Spec.Name) return reconcile.Result{Requeue: true}, nil } + if err != nil { + return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if repository exists") + } if (curRepository.Description != hr.Spec.Description) || (curRepository.RetentionDays != float64(hr.Spec.Retention.TimeInDays)) || diff --git a/controllers/humioscheduledsearch_annotations.go b/controllers/humioscheduledsearch_annotations.go deleted file mode 100644 index f02a6392..00000000 --- a/controllers/humioscheduledsearch_annotations.go +++ /dev/null @@ -1,42 +0,0 @@ -package controllers - -import ( - "context" - "fmt" - - humioapi "github.com/humio/cli/api" - humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/humio" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/reconcile" -) - -func (r *HumioScheduledSearchReconciler) reconcileHumioScheduledSearchAnnotations(ctx context.Context, addedScheduledSearch *humioapi.ScheduledSearch, hss *humiov1alpha1.HumioScheduledSearch, req ctrl.Request) (reconcile.Result, error) { - r.Log.Info(fmt.Sprintf("Adding annotations to scheduled search %q", addedScheduledSearch.Name)) - currentScheduledSearch := &humiov1alpha1.HumioScheduledSearch{} - err := r.Get(ctx, req.NamespacedName, currentScheduledSearch) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to add annotations to scheduled search") - } - - // Copy annotations from the scheduled search transformer to get the current scheduled search annotations - hydratedHumioScheduledSearch := &humiov1alpha1.HumioScheduledSearch{} - if err = humio.ScheduledSearchHydrate(hydratedHumioScheduledSearch, addedScheduledSearch); err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to hydrate scheduled search") - } - - if len(currentScheduledSearch.ObjectMeta.Annotations) < 1 { - currentScheduledSearch.ObjectMeta.Annotations = make(map[string]string) - } - for k, v := range hydratedHumioScheduledSearch.Annotations { - currentScheduledSearch.ObjectMeta.Annotations[k] = v - } - - err = r.Update(ctx, currentScheduledSearch) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "failed to add annotations to scheduled search") - } - - r.Log.Info("Added annotations to ScheduledSearch", "ScheduledSearch", hss.Spec.Name) - return reconcile.Result{}, nil -} diff --git a/controllers/humioscheduledsearch_controller.go b/controllers/humioscheduledsearch_controller.go index 533dc462..31d6b38e 100644 --- a/controllers/humioscheduledsearch_controller.go +++ b/controllers/humioscheduledsearch_controller.go @@ -87,13 +87,13 @@ func (r *HumioScheduledSearchReconciler) Reconcile(ctx context.Context, req ctrl } defer func(ctx context.Context, humioClient humio.Client, hss *humiov1alpha1.HumioScheduledSearch) { - curScheduledSearch, err := r.HumioClient.GetScheduledSearch(cluster.Config(), req, hss) + _, err := r.HumioClient.GetScheduledSearch(cluster.Config(), req, hss) if errors.As(err, &humioapi.EntityNotFound{}) { _ = r.setState(ctx, humiov1alpha1.HumioScheduledSearchStateNotFound, hss) return } - if err != nil || curScheduledSearch == nil { - _ = r.setState(ctx, humiov1alpha1.HumioScheduledSearchStateConfigError, hss) + if err != nil { + _ = r.setState(ctx, humiov1alpha1.HumioScheduledSearchStateUnknown, hss) return } _ = r.setState(ctx, humiov1alpha1.HumioScheduledSearchStateExists, hss) @@ -148,12 +148,7 @@ func (r *HumioScheduledSearchReconciler) reconcileHumioScheduledSearch(ctx conte if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not create scheduled search") } - r.Log.Info("Created scheduled search", "ScheduledSearch", hss.Spec.Name) - - result, err := r.reconcileHumioScheduledSearchAnnotations(ctx, addedScheduledSearch, hss, req) - if err != nil { - return result, err - } + r.Log.Info("Created scheduled search", "ScheduledSearch", hss.Spec.Name, "ID", addedScheduledSearch.ID) return reconcile.Result{Requeue: true}, nil } if err != nil { @@ -164,10 +159,7 @@ func (r *HumioScheduledSearchReconciler) reconcileHumioScheduledSearch(ctx conte if err := r.HumioClient.ValidateActionsForScheduledSearch(config, req, hss); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not get action id mapping") } - expectedScheduledSearch, err := humio.ScheduledSearchTransform(hss) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not parse expected ScheduledSearch") - } + expectedScheduledSearch := humio.ScheduledSearchTransform(hss) sanitizeScheduledSearch(curScheduledSearch) if !reflect.DeepEqual(*curScheduledSearch, *expectedScheduledSearch) { @@ -209,5 +201,6 @@ func (r *HumioScheduledSearchReconciler) logErrorAndReturn(err error, msg string } func sanitizeScheduledSearch(scheduledSearch *humioapi.ScheduledSearch) { + scheduledSearch.ID = "" scheduledSearch.RunAsUserID = "" } diff --git a/controllers/humioview_controller.go b/controllers/humioview_controller.go index 146673b9..e56e04e3 100644 --- a/controllers/humioview_controller.go +++ b/controllers/humioview_controller.go @@ -18,8 +18,8 @@ package controllers import ( "context" + "errors" "fmt" - "reflect" "sort" "time" @@ -84,32 +84,6 @@ func (r *HumioViewReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( return reconcile.Result{RequeueAfter: 5 * time.Second}, r.logErrorAndReturn(err, "unable to obtain humio client config") } - defer func(ctx context.Context, humioClient humio.Client, hv *humiov1alpha1.HumioView) { - curView, err := r.HumioClient.GetView(cluster.Config(), req, hv) - if err != nil { - _ = r.setState(ctx, humiov1alpha1.HumioViewStateUnknown, hv) - return - } - emptyView := humioapi.View{} - if reflect.DeepEqual(emptyView, *curView) { - _ = r.setState(ctx, humiov1alpha1.HumioViewStateNotFound, hv) - return - } - _ = r.setState(ctx, humiov1alpha1.HumioViewStateExists, hv) - }(ctx, r.HumioClient, hv) - - r.Log.Info("get current view") - curView, err := r.HumioClient.GetView(cluster.Config(), req, hv) - if err != nil { - return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if view exists") - } - - return r.reconcileHumioView(ctx, cluster.Config(), curView, hv, req) -} - -func (r *HumioViewReconciler) reconcileHumioView(ctx context.Context, config *humioapi.Config, curView *humioapi.View, hv *humiov1alpha1.HumioView, req reconcile.Request) (reconcile.Result, error) { - emptyView := humioapi.View{} - // Delete r.Log.Info("Checking if view is marked to be deleted") isMarkedForDeletion := hv.GetDeletionTimestamp() != nil @@ -120,7 +94,7 @@ func (r *HumioViewReconciler) reconcileHumioView(ctx context.Context, config *hu // finalization logic fails, don't remove the finalizer so // that we can retry during the next reconciliation. r.Log.Info("Deleting View") - if err := r.HumioClient.DeleteView(config, req, hv); err != nil { + if err := r.HumioClient.DeleteView(cluster.Config(), req, hv); err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "Delete view returned error") } @@ -147,16 +121,33 @@ func (r *HumioViewReconciler) reconcileHumioView(ctx context.Context, config *hu return reconcile.Result{Requeue: true}, nil } - // Add View - if reflect.DeepEqual(emptyView, *curView) { + defer func(ctx context.Context, humioClient humio.Client, hv *humiov1alpha1.HumioView) { + _, err := r.HumioClient.GetView(cluster.Config(), req, hv) + if errors.As(err, &humioapi.EntityNotFound{}) { + _ = r.setState(ctx, humiov1alpha1.HumioViewStateNotFound, hv) + return + } + if err != nil { + _ = r.setState(ctx, humiov1alpha1.HumioViewStateUnknown, hv) + return + } + _ = r.setState(ctx, humiov1alpha1.HumioViewStateExists, hv) + }(ctx, r.HumioClient, hv) + + r.Log.Info("get current view") + curView, err := r.HumioClient.GetView(cluster.Config(), req, hv) + if errors.As(err, &humioapi.EntityNotFound{}) { r.Log.Info("View doesn't exist. Now adding view") - _, err := r.HumioClient.AddView(config, req, hv) + _, err := r.HumioClient.AddView(cluster.Config(), req, hv) if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not create view") } r.Log.Info("created view", "ViewName", hv.Spec.Name) return reconcile.Result{Requeue: true}, nil } + if err != nil { + return reconcile.Result{}, r.logErrorAndReturn(err, "could not check if view exists") + } // Update if viewConnectionsDiffer(curView.Connections, hv.GetViewConnections()) || @@ -169,7 +160,7 @@ func (r *HumioViewReconciler) reconcileHumioView(ctx context.Context, config *hu curView.Connections, curView.Description, curView.AutomaticSearch)) - _, err := r.HumioClient.UpdateView(config, req, hv) + _, err := r.HumioClient.UpdateView(cluster.Config(), req, hv) if err != nil { return reconcile.Result{}, r.logErrorAndReturn(err, "could not update view") } diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index 7a4384c1..35a7bc17 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -56,12 +56,12 @@ var _ = Describe("HumioCluster Controller", func() { BeforeEach(func() { // failed test runs that don't clean up leave resources behind. - humioClientForTestSuite.ClearHumioClientConnections() + testHumioClient.ClearHumioClientConnections() }) AfterEach(func() { // Add any teardown steps that needs to be executed after each test - humioClientForTestSuite.ClearHumioClientConnections() + testHumioClient.ClearHumioClientConnections() }) // Add Tests for OpenAPI validation (or additional CRD features) specified in @@ -79,7 +79,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) }) }) @@ -94,7 +94,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - createAndBootstrapMultiNodePoolCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning) + createAndBootstrapMultiNodePoolCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning) Eventually(func() error { _, err := kubernetes.GetService(ctx, k8sClient, controllers.NewHumioNodeManagerFromHumioNodePool(toCreate, &toCreate.Spec.NodePools[0]).GetServiceName(), key.Namespace) @@ -143,7 +143,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - createAndBootstrapMultiNodePoolCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning) + createAndBootstrapMultiNodePoolCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning) _, err := kubernetes.GetService(ctx, k8sClient, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetServiceName(), key.Namespace) Expect(k8serrors.IsNotFound(err)).Should(BeTrue()) @@ -163,7 +163,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) }) }) @@ -186,7 +186,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) }) }) @@ -201,7 +201,7 @@ var _ = Describe("HumioCluster Controller", func() { toCreate.Spec.Image = oldUnsupportedHumioVersion ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateConfigError, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateConfigError, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) var updatedHumioCluster humiov1alpha1.HumioCluster suite.UsingClusterBy(key.Name, "should indicate cluster configuration error") @@ -236,7 +236,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) revisionKey, _ := controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetHumioClusterNodePoolRevisionAnnotation() @@ -309,7 +309,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) originalAffinity := toCreate.Spec.Affinity @@ -421,7 +421,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) revisionKey, _ := controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetHumioClusterNodePoolRevisionAnnotation() @@ -497,7 +497,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) revisionKey, _ := controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetHumioClusterNodePoolRevisionAnnotation() @@ -592,7 +592,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) revisionKey, _ := controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetHumioClusterNodePoolRevisionAnnotation() @@ -668,7 +668,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) revisionKey, _ := controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetHumioClusterNodePoolRevisionAnnotation() @@ -742,7 +742,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) revisionKey, _ := controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetHumioClusterNodePoolRevisionAnnotation() @@ -825,7 +825,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - createAndBootstrapMultiNodePoolCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning) + createAndBootstrapMultiNodePoolCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning) defer suite.CleanupCluster(ctx, k8sClient, toCreate) mainNodePoolManager := controllers.NewHumioNodeManagerFromHumioCluster(toCreate) @@ -999,7 +999,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) @@ -1105,7 +1105,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) var updatedHumioCluster humiov1alpha1.HumioCluster @@ -1222,7 +1222,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating a cluster with default helper image") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Validating pod uses default helper image as init container") @@ -1339,7 +1339,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) var updatedHumioCluster humiov1alpha1.HumioCluster @@ -1503,7 +1503,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - createAndBootstrapMultiNodePoolCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning) + createAndBootstrapMultiNodePoolCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning) defer suite.CleanupCluster(ctx, k8sClient, toCreate) mainNodePoolManager := controllers.NewHumioNodeManagerFromHumioCluster(toCreate) @@ -1773,7 +1773,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Waiting for ingresses to be created") @@ -1932,7 +1932,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) Eventually(func() bool { @@ -1959,7 +1959,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) Eventually(func() bool { @@ -1986,7 +1986,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) svc, _ := kubernetes.GetService(ctx, k8sClient, key.Name, key.Namespace) @@ -2238,7 +2238,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully without ephemeral disks") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) hnp := controllers.NewHumioNodeManagerFromHumioCluster(toCreate) @@ -2284,7 +2284,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) hnp := controllers.NewHumioNodeManagerFromHumioCluster(toCreate) clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, hnp.GetPodLabels()) @@ -2328,7 +2328,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) humioServiceAccountName := fmt.Sprintf("%s-%s", key.Name, controllers.HumioServiceAccountNameSuffix) @@ -2386,7 +2386,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) @@ -2460,7 +2460,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) @@ -2558,7 +2558,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) @@ -2806,7 +2806,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully with extra kafka configs") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetPodLabels()) @@ -2948,7 +2948,7 @@ var _ = Describe("HumioCluster Controller", func() { ` suite.UsingClusterBy(key.Name, "Creating the cluster successfully with view group permissions") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming config map was created") @@ -3118,7 +3118,7 @@ var _ = Describe("HumioCluster Controller", func() { ` suite.UsingClusterBy(key.Name, "Creating the cluster successfully with role permissions") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming config map was created") @@ -3243,7 +3243,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Bootstrapping the cluster successfully without persistent volumes") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) Expect(kubernetes.ListPersistentVolumeClaims(ctx, k8sClient, key.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(toCreate).GetNodePoolLabels())).To(HaveLen(0)) @@ -3308,7 +3308,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) initialExpectedVolumesCount := 6 @@ -3397,7 +3397,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming PUBLIC_URL is set to default value and PROXY_PREFIX_URL is not set") @@ -3470,7 +3470,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming PUBLIC_URL is set to default value and PROXY_PREFIX_URL is not set") @@ -3774,7 +3774,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming ingress objects do not have TLS configured") @@ -3806,7 +3806,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully without any Hostnames defined") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateConfigError, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateConfigError, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming we did not create any ingresses") @@ -4108,7 +4108,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming init container is using the correct service account") @@ -4166,7 +4166,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming init container is using the correct service account") @@ -4234,7 +4234,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming service was created using the correct annotations") @@ -4271,7 +4271,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming the humio pods use the requested tolerations") @@ -4299,7 +4299,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming the humio pods use the requested topology spread constraint") @@ -4330,7 +4330,7 @@ var _ = Describe("HumioCluster Controller", func() { Expect(k8sClient.Create(ctx, priorityClass)).To(Succeed()) suite.UsingClusterBy(key.Name, "Creating the cluster successfully") - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming the humio pods use the requested priority class name") @@ -4357,7 +4357,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming service was created using the correct annotations") @@ -4387,7 +4387,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming the humio pods are not using shared process namespace nor additional sidecars") @@ -4480,7 +4480,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating Humio cluster without a termination grace period set") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Validating pod is created with the default grace period") @@ -4553,7 +4553,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully with a license secret") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) secretName := fmt.Sprintf("%s-license", key.Name) @@ -4652,7 +4652,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Ensuring the state is Running") @@ -4695,7 +4695,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming the humio pods are not using env var source") @@ -4799,7 +4799,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Confirming the humio pods are not using env var source") @@ -4900,7 +4900,7 @@ var _ = Describe("HumioCluster Controller", func() { suite.UsingClusterBy(key.Name, "Creating the cluster successfully") ctx := context.Background() - suite.CreateAndBootstrapCluster(ctx, k8sClient, humioClientForTestSuite, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) + suite.CreateAndBootstrapCluster(ctx, k8sClient, testHumioClient, toCreate, true, humiov1alpha1.HumioClusterStateRunning, testTimeout) defer suite.CleanupCluster(ctx, k8sClient, toCreate) suite.UsingClusterBy(key.Name, "Removing the node pool label from the pod") diff --git a/controllers/suite/clusters/suite_test.go b/controllers/suite/clusters/suite_test.go index c8411c2c..c4687ac3 100644 --- a/controllers/suite/clusters/suite_test.go +++ b/controllers/suite/clusters/suite_test.go @@ -67,15 +67,7 @@ import ( var k8sClient client.Client var testEnv *envtest.Environment var k8sManager ctrl.Manager -var humioClientForHumioAction humio.Client -var humioClientForHumioAlert humio.Client -var humioClientForHumioCluster humio.Client -var humioClientForHumioExternalCluster humio.Client -var humioClientForHumioIngestToken humio.Client -var humioClientForHumioParser humio.Client -var humioClientForHumioRepository humio.Client -var humioClientForHumioView humio.Client -var humioClientForTestSuite humio.Client +var testHumioClient humio.Client var testTimeout time.Duration var testProcessNamespace string var err error @@ -103,15 +95,7 @@ var _ = BeforeSuite(func() { testEnv = &envtest.Environment{ UseExistingCluster: &useExistingCluster, } - humioClientForTestSuite = humio.NewClient(log, &humioapi.Config{}, "") - humioClientForHumioAction = humio.NewClient(log, &humioapi.Config{}, "") - humioClientForHumioAlert = humio.NewClient(log, &humioapi.Config{}, "") - humioClientForHumioCluster = humio.NewClient(log, &humioapi.Config{}, "") - humioClientForHumioExternalCluster = humio.NewClient(log, &humioapi.Config{}, "") - humioClientForHumioIngestToken = humio.NewClient(log, &humioapi.Config{}, "") - humioClientForHumioParser = humio.NewClient(log, &humioapi.Config{}, "") - humioClientForHumioRepository = humio.NewClient(log, &humioapi.Config{}, "") - humioClientForHumioView = humio.NewClient(log, &humioapi.Config{}, "") + testHumioClient = humio.NewClient(log, &humioapi.Config{}, "") } else { testTimeout = time.Second * 30 testEnv = &envtest.Environment{ @@ -119,15 +103,7 @@ var _ = BeforeSuite(func() { CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, ErrorIfCRDPathMissing: true, } - humioClientForTestSuite = humio.NewMockClient(humioapi.Cluster{}, nil) - humioClientForHumioAction = humio.NewMockClient(humioapi.Cluster{}, nil) - humioClientForHumioAlert = humio.NewMockClient(humioapi.Cluster{}, nil) - humioClientForHumioCluster = humio.NewMockClient(humioapi.Cluster{}, nil) - humioClientForHumioExternalCluster = humio.NewMockClient(humioapi.Cluster{}, nil) - humioClientForHumioIngestToken = humio.NewMockClient(humioapi.Cluster{}, nil) - humioClientForHumioParser = humio.NewMockClient(humioapi.Cluster{}, nil) - humioClientForHumioRepository = humio.NewMockClient(humioapi.Cluster{}, nil) - humioClientForHumioView = humio.NewMockClient(humioapi.Cluster{}, nil) + testHumioClient = humio.NewMockClient() } var cfg *rest.Config @@ -164,7 +140,7 @@ var _ = BeforeSuite(func() { err = (&controllers.HumioActionReconciler{ Client: k8sManager.GetClient(), - HumioClient: humioClientForHumioAction, + HumioClient: testHumioClient, BaseLogger: log, Namespace: testProcessNamespace, }).SetupWithManager(k8sManager) @@ -172,7 +148,7 @@ var _ = BeforeSuite(func() { err = (&controllers.HumioAlertReconciler{ Client: k8sManager.GetClient(), - HumioClient: humioClientForHumioAlert, + HumioClient: testHumioClient, BaseLogger: log, Namespace: testProcessNamespace, }).SetupWithManager(k8sManager) @@ -180,7 +156,7 @@ var _ = BeforeSuite(func() { err = (&controllers.HumioClusterReconciler{ Client: k8sManager.GetClient(), - HumioClient: humioClientForHumioCluster, + HumioClient: testHumioClient, BaseLogger: log, Namespace: testProcessNamespace, }).SetupWithManager(k8sManager) @@ -188,7 +164,7 @@ var _ = BeforeSuite(func() { err = (&controllers.HumioExternalClusterReconciler{ Client: k8sManager.GetClient(), - HumioClient: humioClientForHumioExternalCluster, + HumioClient: testHumioClient, BaseLogger: log, Namespace: testProcessNamespace, }).SetupWithManager(k8sManager) @@ -196,7 +172,7 @@ var _ = BeforeSuite(func() { err = (&controllers.HumioIngestTokenReconciler{ Client: k8sManager.GetClient(), - HumioClient: humioClientForHumioIngestToken, + HumioClient: testHumioClient, BaseLogger: log, Namespace: testProcessNamespace, }).SetupWithManager(k8sManager) @@ -204,7 +180,7 @@ var _ = BeforeSuite(func() { err = (&controllers.HumioParserReconciler{ Client: k8sManager.GetClient(), - HumioClient: humioClientForHumioParser, + HumioClient: testHumioClient, BaseLogger: log, Namespace: testProcessNamespace, }).SetupWithManager(k8sManager) @@ -212,7 +188,7 @@ var _ = BeforeSuite(func() { err = (&controllers.HumioRepositoryReconciler{ Client: k8sManager.GetClient(), - HumioClient: humioClientForHumioRepository, + HumioClient: testHumioClient, BaseLogger: log, Namespace: testProcessNamespace, }).SetupWithManager(k8sManager) @@ -220,7 +196,7 @@ var _ = BeforeSuite(func() { err = (&controllers.HumioViewReconciler{ Client: k8sManager.GetClient(), - HumioClient: humioClientForHumioView, + HumioClient: testHumioClient, BaseLogger: log, Namespace: testProcessNamespace, }).SetupWithManager(k8sManager) diff --git a/controllers/suite/resources/humioresources_controller_test.go b/controllers/suite/resources/humioresources_controller_test.go index ccf4334c..0185b98b 100644 --- a/controllers/suite/resources/humioresources_controller_test.go +++ b/controllers/suite/resources/humioresources_controller_test.go @@ -99,7 +99,7 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) if os.Getenv("TEST_USE_EXISTING_CLUSTER") != "true" { - Expect(string(ingestTokenSecret.Data["token"])).To(Equal("mocktoken")) + Expect(string(ingestTokenSecret.Data["token"])).ToNot(BeEmpty()) } Expect(ingestTokenSecret.OwnerReferences).Should(HaveLen(1)) @@ -153,7 +153,7 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) if os.Getenv("TEST_USE_EXISTING_CLUSTER") != "true" { - Expect(string(ingestTokenSecret.Data["token"])).To(Equal("mocktoken")) + Expect(string(ingestTokenSecret.Data["token"])).ToNot(BeEmpty()) } suite.UsingClusterBy(clusterKey.Name, "HumioIngestToken: Successfully deleting it") @@ -224,7 +224,7 @@ var _ = Describe("Humio Resources Controllers", func() { Expect(ingestTokenSecret.Labels).Should(HaveKeyWithValue("custom-label", "custom-value")) if os.Getenv("TEST_USE_EXISTING_CLUSTER") != "true" { - Expect(string(ingestTokenSecret.Data["token"])).To(Equal("mocktoken")) + Expect(string(ingestTokenSecret.Data["token"])).ToNot(BeEmpty()) } suite.UsingClusterBy(clusterKey.Name, "HumioIngestToken: Successfully deleting it") @@ -609,20 +609,8 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(initialParser).ToNot(BeNil()) - expectedInitialParser := humioapi.Parser{ - Name: spec.Name, - Script: spec.ParserScript, - FieldsToTag: spec.TagFields, - FieldsToBeRemovedBeforeParsing: []string{}, - } - expectedInitialParser.TestCases = make([]humioapi.ParserTestCase, len(spec.TestData)) - for i := range spec.TestData { - expectedInitialParser.TestCases[i] = humioapi.ParserTestCase{ - Event: humioapi.ParserTestEvent{RawString: spec.TestData[i]}, - Assertions: []humioapi.ParserTestCaseAssertions{}, - } - } - Expect(*initialParser).To(Equal(expectedInitialParser)) + expectedInitialParser := humio.ParserTransform(toCreateParser) + Expect(*initialParser).To(Equal(*expectedInitialParser)) suite.UsingClusterBy(clusterKey.Name, "HumioParser: Updating the parser successfully") updatedScript := "kvParse() | updated" @@ -643,19 +631,7 @@ var _ = Describe("Humio Resources Controllers", func() { }, testTimeout, suite.TestInterval).Should(Succeed()) Expect(updatedParser).ToNot(BeNil()) - expectedUpdatedParser := humioapi.Parser{ - Name: spec.Name, - Script: updatedScript, - FieldsToTag: spec.TagFields, - FieldsToBeRemovedBeforeParsing: []string{}, - } - expectedUpdatedParser.TestCases = make([]humioapi.ParserTestCase, len(spec.TestData)) - for i := range spec.TestData { - expectedUpdatedParser.TestCases[i] = humioapi.ParserTestCase{ - Event: humioapi.ParserTestEvent{RawString: spec.TestData[i]}, - Assertions: []humioapi.ParserTestCaseAssertions{}, - } - } + expectedUpdatedParser := *humio.ParserTransform(fetchedParser) Eventually(func() humioapi.Parser { updatedParser, err := humioClient.GetParser(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedParser) if err != nil { @@ -2783,8 +2759,7 @@ var _ = Describe("Humio Resources Controllers", func() { return err }, testTimeout, suite.TestInterval).Should(Succeed()) - originalAlert, err := humio.AlertTransform(toCreateAlert, actionIdMap) - Expect(err).To(BeNil()) + originalAlert := humio.AlertTransform(toCreateAlert, actionIdMap) Expect(alert.Name).To(Equal(originalAlert.Name)) Expect(alert.Description).To(Equal(originalAlert.Description)) Expect(alert.Actions).To(Equal(originalAlert.Actions)) @@ -2824,8 +2799,7 @@ var _ = Describe("Humio Resources Controllers", func() { Expect(expectedUpdatedAlert).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAlert: Verifying the alert matches the expected") - verifiedAlert, err := humio.AlertTransform(updatedAlert, actionIdMap) - Expect(err).To(BeNil()) + verifiedAlert := humio.AlertTransform(updatedAlert, actionIdMap) Eventually(func() humioapi.Alert { updatedAlert, err := humioClient.GetAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAlert) if err != nil { @@ -2957,8 +2931,7 @@ var _ = Describe("Humio Resources Controllers", func() { return humioClient.ValidateActionsForFilterAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateFilterAlert) }, testTimeout, suite.TestInterval).Should(Succeed()) - originalFilterAlert, err := humio.FilterAlertTransform(toCreateFilterAlert) - Expect(err).To(BeNil()) + originalFilterAlert := humio.FilterAlertTransform(toCreateFilterAlert) Expect(filterAlert.Name).To(Equal(originalFilterAlert.Name)) Expect(filterAlert.Description).To(Equal(originalFilterAlert.Description)) Expect(filterAlert.ThrottleTimeSeconds).To(Equal(originalFilterAlert.ThrottleTimeSeconds)) @@ -2969,8 +2942,7 @@ var _ = Describe("Humio Resources Controllers", func() { Expect(filterAlert.QueryString).To(Equal(originalFilterAlert.QueryString)) createdFilterAlert := toCreateFilterAlert - err = humio.FilterAlertHydrate(createdFilterAlert, filterAlert) - Expect(err).To(BeNil()) + humio.FilterAlertHydrate(createdFilterAlert, filterAlert) Expect(createdFilterAlert.Spec).To(Equal(toCreateFilterAlert.Spec)) suite.UsingClusterBy(clusterKey.Name, "HumioFilterAlert: Updating the filter alert successfully") @@ -3002,11 +2974,10 @@ var _ = Describe("Humio Resources Controllers", func() { Expect(expectedUpdatedFilterAlert).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioFilterAlert: Verifying the alert matches the expected") - verifiedFilterAlert, err := humio.FilterAlertTransform(updatedFilterAlert) + verifiedFilterAlert := humio.FilterAlertTransform(updatedFilterAlert) verifiedFilterAlert.ID = "" verifiedFilterAlert.RunAsUserID = "" - Expect(err).To(BeNil()) Eventually(func() humioapi.FilterAlert { updatedFilterAlert, err := humioClient.GetFilterAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedFilterAlert) if err != nil { @@ -3142,8 +3113,7 @@ var _ = Describe("Humio Resources Controllers", func() { return humioClient.ValidateActionsForAggregateAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateAggregateAlert) }, testTimeout, suite.TestInterval).Should(Succeed()) - originalAggregateAlert, err := humio.AggregateAlertTransform(toCreateAggregateAlert) - Expect(err).To(BeNil()) + originalAggregateAlert := humio.AggregateAlertTransform(toCreateAggregateAlert) Expect(aggregateAlert.Name).To(Equal(originalAggregateAlert.Name)) Expect(aggregateAlert.Description).To(Equal(originalAggregateAlert.Description)) Expect(aggregateAlert.ThrottleTimeSeconds).To(Equal(originalAggregateAlert.ThrottleTimeSeconds)) @@ -3152,7 +3122,7 @@ var _ = Describe("Humio Resources Controllers", func() { Expect(aggregateAlert.Labels).To(Equal(originalAggregateAlert.Labels)) createdAggregateAlert := toCreateAggregateAlert - err = humio.AggregateAlertHydrate(createdAggregateAlert, aggregateAlert) + humio.AggregateAlertHydrate(createdAggregateAlert, aggregateAlert) Expect(err).To(BeNil()) Expect(createdAggregateAlert.Spec).To(Equal(toCreateAggregateAlert.Spec)) @@ -3191,11 +3161,10 @@ var _ = Describe("Humio Resources Controllers", func() { Expect(expectedUpdatedAggregateAlert).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioAggregateAlert: Verifying the alert matches the expected") - verifiedAggregateAlert, err := humio.AggregateAlertTransform(updatedAggregateAlert) + verifiedAggregateAlert := humio.AggregateAlertTransform(updatedAggregateAlert) verifiedAggregateAlert.ID = "" verifiedAggregateAlert.RunAsUserID = "" - Expect(err).To(BeNil()) Eventually(func() humioapi.AggregateAlert { updatedAggregateAlert, err := humioClient.GetAggregateAlert(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedAggregateAlert) if err != nil { @@ -3330,8 +3299,7 @@ var _ = Describe("Humio Resources Controllers", func() { return humioClient.ValidateActionsForScheduledSearch(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, toCreateScheduledSearch) }, testTimeout, suite.TestInterval).Should(Succeed()) - originalScheduledSearch, err := humio.ScheduledSearchTransform(toCreateScheduledSearch) - Expect(err).To(BeNil()) + originalScheduledSearch := humio.ScheduledSearchTransform(toCreateScheduledSearch) Expect(scheduledSearch.Name).To(Equal(originalScheduledSearch.Name)) Expect(scheduledSearch.Description).To(Equal(originalScheduledSearch.Description)) Expect(scheduledSearch.ActionNames).To(Equal(originalScheduledSearch.ActionNames)) @@ -3345,8 +3313,7 @@ var _ = Describe("Humio Resources Controllers", func() { Expect(scheduledSearch.BackfillLimit).To(Equal(originalScheduledSearch.BackfillLimit)) createdScheduledSearch := toCreateScheduledSearch - err = humio.ScheduledSearchHydrate(createdScheduledSearch, scheduledSearch) - Expect(err).To(BeNil()) + humio.ScheduledSearchHydrate(createdScheduledSearch, scheduledSearch) Expect(createdScheduledSearch.Spec).To(Equal(toCreateScheduledSearch.Spec)) suite.UsingClusterBy(clusterKey.Name, "HumioScheduledSearch: Updating the scheduled search successfully") @@ -3384,11 +3351,10 @@ var _ = Describe("Humio Resources Controllers", func() { Expect(expectedUpdatedScheduledSearch).ToNot(BeNil()) suite.UsingClusterBy(clusterKey.Name, "HumioScheduledSearch: Verifying the scheduled search matches the expected") - verifiedScheduledSearch, err := humio.ScheduledSearchTransform(updatedScheduledSearch) + verifiedScheduledSearch := humio.ScheduledSearchTransform(updatedScheduledSearch) verifiedScheduledSearch.ID = "" verifiedScheduledSearch.RunAsUserID = "" - Expect(err).To(BeNil()) Eventually(func() humioapi.ScheduledSearch { updatedScheduledSearch, err := humioClient.GetScheduledSearch(sharedCluster.Config(), reconcile.Request{NamespacedName: clusterKey}, fetchedScheduledSearch) if err != nil { diff --git a/controllers/suite/resources/suite_test.go b/controllers/suite/resources/suite_test.go index 0c77af95..48d1a7c5 100644 --- a/controllers/suite/resources/suite_test.go +++ b/controllers/suite/resources/suite_test.go @@ -111,7 +111,7 @@ var _ = BeforeSuite(func() { CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")}, ErrorIfCRDPathMissing: true, } - humioClient = humio.NewMockClient(humioapi.Cluster{}, nil) + humioClient = humio.NewMockClient() } var cfg *rest.Config diff --git a/go.mod b/go.mod index e2408317..557ed67a 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-logr/logr v1.4.2 github.com/go-logr/zapr v1.3.0 github.com/google/go-cmp v0.6.0 - github.com/humio/cli v0.36.0 + github.com/humio/cli v0.36.1-0.20240813114317-eafdd46e889a github.com/onsi/ginkgo/v2 v2.20.0 github.com/onsi/gomega v1.34.1 github.com/prometheus/client_golang v1.19.0 diff --git a/go.sum b/go.sum index 36d74598..f97a105c 100644 --- a/go.sum +++ b/go.sum @@ -52,8 +52,8 @@ github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQu github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/humio/cli v0.36.0 h1:KAF4natLsnYNp2zyS1xCjDd6TB/pUz0wGootorBjjbA= -github.com/humio/cli v0.36.0/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= +github.com/humio/cli v0.36.1-0.20240813114317-eafdd46e889a h1:1SegzWT5U+6xslFrJgRnMbMVnSkQj19a6tl5u+nRB+A= +github.com/humio/cli v0.36.1-0.20240813114317-eafdd46e889a/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= diff --git a/pkg/humio/action_transform.go b/pkg/humio/action_transform.go index f15fa2b0..e8e43e13 100644 --- a/pkg/humio/action_transform.go +++ b/pkg/humio/action_transform.go @@ -29,8 +29,6 @@ import ( ) const ( - ActionIdentifierAnnotation = "humio.com/action-id" - ActionTypeWebhook = "Webhook" ActionTypeSlack = "Slack" ActionTypeSlackPostMessage = "SlackPostMessage" @@ -389,9 +387,6 @@ func baseAction(ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { action := &humioapi.Action{ Name: ha.Spec.Name, } - if _, ok := ha.ObjectMeta.Annotations[ActionIdentifierAnnotation]; ok { - action.ID = ha.ObjectMeta.Annotations[ActionIdentifierAnnotation] - } return action, nil } diff --git a/pkg/humio/aggregatealert_transform.go b/pkg/humio/aggregatealert_transform.go index 97741c04..8a183d68 100644 --- a/pkg/humio/aggregatealert_transform.go +++ b/pkg/humio/aggregatealert_transform.go @@ -3,14 +3,9 @@ package humio import ( humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const ( - AggregateAlertIdentifierAnnotation = "humio.com/aggregate-alert-id" -) - -func AggregateAlertTransform(haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { +func AggregateAlertTransform(haa *humiov1alpha1.HumioAggregateAlert) *humioapi.AggregateAlert { aggregateAlert := &humioapi.AggregateAlert{ Name: haa.Spec.Name, QueryString: haa.Spec.QueryString, @@ -26,37 +21,25 @@ func AggregateAlertTransform(haa *humiov1alpha1.HumioAggregateAlert) (*humioapi. QueryOwnershipType: humioapi.QueryOwnershipTypeOrganization, } - if _, ok := haa.ObjectMeta.Annotations[AggregateAlertIdentifierAnnotation]; ok { - aggregateAlert.ID = haa.ObjectMeta.Annotations[AggregateAlertIdentifierAnnotation] - } - if aggregateAlert.Labels == nil { aggregateAlert.Labels = []string{} } - return aggregateAlert, nil + return aggregateAlert } -func AggregateAlertHydrate(haa *humiov1alpha1.HumioAggregateAlert, aggregatealert *humioapi.AggregateAlert) error { +func AggregateAlertHydrate(haa *humiov1alpha1.HumioAggregateAlert, aggregateAlert *humioapi.AggregateAlert) { haa.Spec = humiov1alpha1.HumioAggregateAlertSpec{ - Name: aggregatealert.Name, - QueryString: aggregatealert.QueryString, - QueryTimestampType: aggregatealert.QueryTimestampType, - Description: aggregatealert.Description, - SearchIntervalSeconds: aggregatealert.SearchIntervalSeconds, - ThrottleTimeSeconds: aggregatealert.ThrottleTimeSeconds, - ThrottleField: aggregatealert.ThrottleField, - TriggerMode: aggregatealert.TriggerMode, - Enabled: aggregatealert.Enabled, - Actions: aggregatealert.ActionNames, - Labels: aggregatealert.Labels, + Name: aggregateAlert.Name, + QueryString: aggregateAlert.QueryString, + QueryTimestampType: aggregateAlert.QueryTimestampType, + Description: aggregateAlert.Description, + SearchIntervalSeconds: aggregateAlert.SearchIntervalSeconds, + ThrottleTimeSeconds: aggregateAlert.ThrottleTimeSeconds, + ThrottleField: aggregateAlert.ThrottleField, + TriggerMode: aggregateAlert.TriggerMode, + Enabled: aggregateAlert.Enabled, + Actions: aggregateAlert.ActionNames, + Labels: aggregateAlert.Labels, } - - haa.ObjectMeta = metav1.ObjectMeta{ - Annotations: map[string]string{ - AggregateAlertIdentifierAnnotation: aggregatealert.ID, - }, - } - - return nil } diff --git a/pkg/humio/alert_transform.go b/pkg/humio/alert_transform.go index 512542ba..93bea446 100644 --- a/pkg/humio/alert_transform.go +++ b/pkg/humio/alert_transform.go @@ -3,14 +3,9 @@ package humio import ( humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const ( - AlertIdentifierAnnotation = "humio.com/alert-id" -) - -func AlertTransform(ha *humiov1alpha1.HumioAlert, actionIdMap map[string]string) (*humioapi.Alert, error) { +func AlertTransform(ha *humiov1alpha1.HumioAlert, actionIdMap map[string]string) *humioapi.Alert { alert := &humioapi.Alert{ Name: ha.Spec.Name, QueryString: ha.Spec.Query.QueryString, @@ -27,14 +22,10 @@ func AlertTransform(ha *humiov1alpha1.HumioAlert, actionIdMap map[string]string) alert.QueryStart = "1d" } - if _, ok := ha.ObjectMeta.Annotations[AlertIdentifierAnnotation]; ok { - alert.ID = ha.ObjectMeta.Annotations[AlertIdentifierAnnotation] - } - - return alert, nil + return alert } -func AlertHydrate(ha *humiov1alpha1.HumioAlert, alert *humioapi.Alert, actionIdMap map[string]string) error { +func AlertHydrate(ha *humiov1alpha1.HumioAlert, alert *humioapi.Alert, actionIdMap map[string]string) { ha.Spec = humiov1alpha1.HumioAlertSpec{ Name: alert.Name, Query: humiov1alpha1.HumioQuery{ @@ -49,13 +40,7 @@ func AlertHydrate(ha *humiov1alpha1.HumioAlert, alert *humioapi.Alert, actionIdM Labels: alert.Labels, } - ha.ObjectMeta = metav1.ObjectMeta{ - Annotations: map[string]string{ - AlertIdentifierAnnotation: alert.ID, - }, - } - - return nil + return } func actionIdsFromActionMap(actionList []string, actionIdMap map[string]string) []string { diff --git a/pkg/humio/client.go b/pkg/humio/client.go index 0204630a..f2e7eb93 100644 --- a/pkg/humio/client.go +++ b/pkg/humio/client.go @@ -261,16 +261,7 @@ func (h *ClientConfig) AddIngestToken(config *humioapi.Config, req reconcile.Req } func (h *ClientConfig) GetIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { - tokens, err := h.GetHumioClient(config, req).IngestTokens().List(hit.Spec.RepositoryName) - if err != nil { - return &humioapi.IngestToken{}, err - } - for _, token := range tokens { - if token.Name == hit.Spec.Name { - return &token, nil - } - } - return &humioapi.IngestToken{}, nil + return h.GetHumioClient(config, req).IngestTokens().Get(hit.Spec.RepositoryName, hit.Spec.Name) } func (h *ClientConfig) UpdateIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { @@ -423,6 +414,10 @@ func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.R } func (h *ClientConfig) DeleteRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) error { + _, err := h.GetRepository(config, req, hr) + if errors.As(err, &humioapi.EntityNotFound{}) { + return nil + } // TODO: perhaps we should allow calls to DeleteRepository() to include the reason instead of hardcoding it return h.GetHumioClient(config, req).Repositories().Delete( hr.Spec.Name, @@ -503,6 +498,10 @@ func (h *ClientConfig) UpdateView(config *humioapi.Config, req reconcile.Request } func (h *ClientConfig) DeleteView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) error { + _, err := h.GetView(config, req, hv) + if errors.As(err, &humioapi.EntityNotFound{}) { + return nil + } return h.GetHumioClient(config, req).Views().Delete(hv.Spec.Name, "Deleted by humio-operator") } @@ -534,7 +533,7 @@ func (h *ClientConfig) GetAction(config *humioapi.Config, req reconcile.Request, action, err := h.GetHumioClient(config, req).Actions().Get(ha.Spec.ViewName, ha.Spec.Name) if err != nil { - return action, fmt.Errorf("error when trying to get action %+v, name=%s, view=%s: %w", action, ha.Spec.Name, ha.Spec.ViewName, err) + return nil, fmt.Errorf("error when trying to get action %+v, name=%s, view=%s: %w", action, ha.Spec.Name, ha.Spec.ViewName, err) } if action == nil || action.Name == "" { @@ -573,6 +572,12 @@ func (h *ClientConfig) UpdateAction(config *humioapi.Config, req reconcile.Reque return action, err } + currentAction, err := h.GetAction(config, req, ha) + if err != nil { + return nil, fmt.Errorf("could not find action with name: %q", ha.Spec.Name) + } + action.ID = currentAction.ID + return h.GetHumioClient(config, req).Actions().Update(ha.Spec.ViewName, action) } @@ -631,11 +636,8 @@ func (h *ClientConfig) AddAlert(config *humioapi.Config, req reconcile.Request, if err != nil { return &humioapi.Alert{}, fmt.Errorf("could not get action id mapping: %w", err) } - alert, err := AlertTransform(ha, actionIdMap) - if err != nil { - return alert, err - } + alert := AlertTransform(ha, actionIdMap) createdAlert, err := h.GetHumioClient(config, req).Alerts().Add(ha.Spec.ViewName, alert) if err != nil { return createdAlert, fmt.Errorf("got error when attempting to add alert: %w, alert: %#v", err, *alert) @@ -653,11 +655,8 @@ func (h *ClientConfig) UpdateAlert(config *humioapi.Config, req reconcile.Reques if err != nil { return &humioapi.Alert{}, fmt.Errorf("could not get action id mapping: %w", err) } - alert, err := AlertTransform(ha, actionIdMap) - if err != nil { - return alert, err - } + alert := AlertTransform(ha, actionIdMap) currentAlert, err := h.GetAlert(config, req, ha) if err != nil { return &humioapi.Alert{}, fmt.Errorf("could not find alert with name: %q", alert.Name) @@ -714,11 +713,8 @@ func (h *ClientConfig) AddFilterAlert(config *humioapi.Config, req reconcile.Req if err = h.ValidateActionsForFilterAlert(config, req, hfa); err != nil { return &humioapi.FilterAlert{}, fmt.Errorf("could not get action id mapping: %w", err) } - filterAlert, err := FilterAlertTransform(hfa) - if err != nil { - return filterAlert, err - } + filterAlert := FilterAlertTransform(hfa) createdAlert, err := h.GetHumioClient(config, req).FilterAlerts().Create(hfa.Spec.ViewName, filterAlert) if err != nil { return createdAlert, fmt.Errorf("got error when attempting to add filter alert: %w, filteralert: %#v", err, *filterAlert) @@ -734,11 +730,8 @@ func (h *ClientConfig) UpdateFilterAlert(config *humioapi.Config, req reconcile. if err = h.ValidateActionsForFilterAlert(config, req, hfa); err != nil { return &humioapi.FilterAlert{}, fmt.Errorf("could not get action id mapping: %w", err) } - filterAlert, err := FilterAlertTransform(hfa) - if err != nil { - return filterAlert, err - } + filterAlert := FilterAlertTransform(hfa) currentAlert, err := h.GetFilterAlert(config, req, hfa) if err != nil { return &humioapi.FilterAlert{}, fmt.Errorf("could not find filter alert with name: %q", filterAlert.Name) @@ -767,10 +760,7 @@ func (h *ClientConfig) AddScheduledSearch(config *humioapi.Config, req reconcile if err = h.ValidateActionsForScheduledSearch(config, req, hss); err != nil { return &humioapi.ScheduledSearch{}, fmt.Errorf("could not get action id mapping: %w", err) } - scheduledSearch, err := ScheduledSearchTransform(hss) - if err != nil { - return scheduledSearch, err - } + scheduledSearch := ScheduledSearchTransform(hss) createdScheduledSearch, err := h.GetHumioClient(config, req).ScheduledSearches().Create(hss.Spec.ViewName, scheduledSearch) if err != nil { @@ -818,10 +808,7 @@ func (h *ClientConfig) UpdateScheduledSearch(config *humioapi.Config, req reconc if err = h.ValidateActionsForScheduledSearch(config, req, hss); err != nil { return &humioapi.ScheduledSearch{}, fmt.Errorf("could not get action id mapping: %w", err) } - scheduledSearch, err := ScheduledSearchTransform(hss) - if err != nil { - return scheduledSearch, err - } + scheduledSearch := ScheduledSearchTransform(hss) currentScheduledSearch, err := h.GetScheduledSearch(config, req, hss) if err != nil { @@ -904,11 +891,7 @@ func (h *ClientConfig) AddAggregateAlert(config *humioapi.Config, req reconcile. return &humioapi.AggregateAlert{}, fmt.Errorf("could not get action id mapping: %w", err) } - aggregateAlert, err := AggregateAlertTransform(haa) - if err != nil { - return aggregateAlert, err - } - + aggregateAlert := AggregateAlertTransform(haa) createdAggregateAlert, err := h.GetHumioClient(config, req).AggregateAlerts().Create(haa.Spec.ViewName, aggregateAlert) if err != nil { return createdAggregateAlert, fmt.Errorf("got error when attempting to add aggregate alert: %w, aggregatealert: %#v", err, *aggregateAlert) @@ -955,11 +938,7 @@ func (h *ClientConfig) UpdateAggregateAlert(config *humioapi.Config, req reconci if err = h.ValidateActionsForAggregateAlert(config, req, haa); err != nil { return &humioapi.AggregateAlert{}, fmt.Errorf("could not get action id mapping: %w", err) } - aggregateAlert, err := AggregateAlertTransform(haa) - if err != nil { - return aggregateAlert, err - } - + aggregateAlert := AggregateAlertTransform(haa) currentAggregateAlert, err := h.GetAggregateAlert(config, req, haa) if err != nil { return &humioapi.AggregateAlert{}, fmt.Errorf("could not find aggregate alert with namer: %q", aggregateAlert.Name) diff --git a/pkg/humio/client_mock.go b/pkg/humio/client_mock.go index 8c5929f3..260c5c28 100644 --- a/pkg/humio/client_mock.go +++ b/pkg/humio/client_mock.go @@ -20,51 +20,66 @@ import ( "crypto/sha512" "encoding/hex" "fmt" + "github.com/humio/humio-operator/pkg/helpers" "net/url" - "reflect" + "sync" humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - "github.com/humio/humio-operator/pkg/helpers" "github.com/humio/humio-operator/pkg/kubernetes" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) +var ( + humioClientMu sync.Mutex +) + +type resourceKey struct { + // clusterName holds the value of the cluster + clusterName string + + // searchDomainName is the name of the repository or view + searchDomainName string + + // resourceName is the name of resource, like IngestToken, Parser, etc. + resourceName string +} + type ClientMock struct { - Cluster humioapi.Cluster - ClusterError error - IngestToken humioapi.IngestToken - Parser humioapi.Parser - Repository humioapi.Repository - View humioapi.View - OnPremLicense humioapi.OnPremLicense - Action humioapi.Action - Alert humioapi.Alert - FilterAlert humioapi.FilterAlert - AggregateAlert humioapi.AggregateAlert - ScheduledSearch humioapi.ScheduledSearch + OnPremLicense map[resourceKey]humioapi.OnPremLicense + + Repository map[resourceKey]humioapi.Repository + View map[resourceKey]humioapi.View + + IngestToken map[resourceKey]humioapi.IngestToken + Parser map[resourceKey]humioapi.Parser + Action map[resourceKey]humioapi.Action + Alert map[resourceKey]humioapi.Alert + FilterAlert map[resourceKey]humioapi.FilterAlert + AggregateAlert map[resourceKey]humioapi.AggregateAlert + ScheduledSearch map[resourceKey]humioapi.ScheduledSearch } type MockClientConfig struct { apiClient *ClientMock } -func NewMockClient(cluster humioapi.Cluster, clusterError error) *MockClientConfig { +func NewMockClient() *MockClientConfig { mockClientConfig := &MockClientConfig{ apiClient: &ClientMock{ - Cluster: cluster, - ClusterError: clusterError, - IngestToken: humioapi.IngestToken{}, - Parser: humioapi.Parser{}, - Repository: humioapi.Repository{}, - View: humioapi.View{}, - OnPremLicense: humioapi.OnPremLicense{}, - Action: humioapi.Action{}, - Alert: humioapi.Alert{}, - FilterAlert: humioapi.FilterAlert{}, - AggregateAlert: humioapi.AggregateAlert{}, - ScheduledSearch: humioapi.ScheduledSearch{}, + OnPremLicense: map[resourceKey]humioapi.OnPremLicense{}, + + Repository: make(map[resourceKey]humioapi.Repository), + View: make(map[resourceKey]humioapi.View), + + IngestToken: make(map[resourceKey]humioapi.IngestToken), + Parser: make(map[resourceKey]humioapi.Parser), + Action: make(map[resourceKey]humioapi.Action), + Alert: make(map[resourceKey]humioapi.Alert), + FilterAlert: make(map[resourceKey]humioapi.FilterAlert), + AggregateAlert: make(map[resourceKey]humioapi.AggregateAlert), + ScheduledSearch: make(map[resourceKey]humioapi.ScheduledSearch), }, } @@ -79,10 +94,7 @@ func (h *MockClientConfig) Status(config *humioapi.Config, req reconcile.Request } func (h *MockClientConfig) GetClusters(config *humioapi.Config, req reconcile.Request) (humioapi.Cluster, error) { - if h.apiClient.ClusterError != nil { - return humioapi.Cluster{}, h.apiClient.ClusterError - } - return h.apiClient.Cluster, nil + return humioapi.Cluster{}, fmt.Errorf("not implemented") } func (h *MockClientConfig) GetBaseURL(config *humioapi.Config, req reconcile.Request, hc *humiov1alpha1.HumioCluster) *url.URL { @@ -95,96 +107,262 @@ func (h *MockClientConfig) TestAPIToken(config *humioapi.Config, req reconcile.R } func (h *MockClientConfig) AddIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { - h.apiClient.IngestToken = humioapi.IngestToken{ - Name: hit.Spec.Name, - AssignedParser: hit.Spec.ParserName, - Token: "mocktoken", + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), + searchDomainName: hit.Spec.RepositoryName, + resourceName: hit.Spec.Name, + } + + if _, found := h.apiClient.IngestToken[key]; found { + return nil, fmt.Errorf("ingest token already exists with name %s", hit.Spec.Name) } - return &h.apiClient.IngestToken, nil + + value := IngestTokenTransform(hit) + if value.Token == "" { + value.Token = kubernetes.RandomString() + } + h.apiClient.IngestToken[key] = *value + return value, nil } func (h *MockClientConfig) GetIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { - return &h.apiClient.IngestToken, nil + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), + searchDomainName: hit.Spec.RepositoryName, + resourceName: hit.Spec.Name, + } + if value, found := h.apiClient.IngestToken[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find ingest token in repository %s with name %s, err=%w", hit.Spec.RepositoryName, hit.Spec.Name, humioapi.EntityNotFound{}) } func (h *MockClientConfig) UpdateIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) (*humioapi.IngestToken, error) { - return h.AddIngestToken(config, req, hit) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), + searchDomainName: hit.Spec.RepositoryName, + resourceName: hit.Spec.Name, + } + + if _, found := h.apiClient.IngestToken[key]; !found { + return nil, fmt.Errorf("ingest token not found with name %s, err=%w", hit.Spec.Name, humioapi.EntityNotFound{}) + } + + value := IngestTokenTransform(hit) + if value.Token == "" { + value.Token = h.apiClient.IngestToken[key].Token + } + h.apiClient.IngestToken[key] = *value + return value, nil } func (h *MockClientConfig) DeleteIngestToken(config *humioapi.Config, req reconcile.Request, hit *humiov1alpha1.HumioIngestToken) error { - h.apiClient.IngestToken = humioapi.IngestToken{} + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), + searchDomainName: hit.Spec.RepositoryName, + resourceName: hit.Spec.Name, + } + + delete(h.apiClient.IngestToken, key) return nil } func (h *MockClientConfig) AddParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) (*humioapi.Parser, error) { - h.apiClient.Parser = humioapi.Parser{ - Name: hp.Spec.Name, - Script: hp.Spec.ParserScript, - FieldsToTag: hp.Spec.TagFields, - FieldsToBeRemovedBeforeParsing: []string{}, + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), + searchDomainName: hp.Spec.RepositoryName, + resourceName: hp.Spec.Name, } - testCasesGQL := make([]humioapi.ParserTestCase, len(hp.Spec.TestData)) - for i := range hp.Spec.TestData { - testCasesGQL[i] = humioapi.ParserTestCase{ - Event: humioapi.ParserTestEvent{RawString: hp.Spec.TestData[i]}, - Assertions: []humioapi.ParserTestCaseAssertions{}, - } + if _, found := h.apiClient.Parser[key]; found { + return nil, fmt.Errorf("parser already exists with name %s", hp.Spec.Name) } - h.apiClient.Parser.TestCases = testCasesGQL - return &h.apiClient.Parser, nil + value := ParserTransform(hp) + if value.ID == "" { + value.ID = kubernetes.RandomString() + } + h.apiClient.Parser[key] = *value + return value, nil } func (h *MockClientConfig) GetParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) (*humioapi.Parser, error) { - if h.apiClient.Parser.Name == "" { - return nil, fmt.Errorf("could not find parser in view %q with name %q, err=%w", hp.Spec.RepositoryName, hp.Spec.Name, humioapi.EntityNotFound{}) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), + searchDomainName: hp.Spec.RepositoryName, + resourceName: hp.Spec.Name, } + if value, found := h.apiClient.Parser[key]; found { + return &value, nil - return &h.apiClient.Parser, nil + } + return nil, fmt.Errorf("could not find parser in repository %s with name %s, err=%w", hp.Spec.RepositoryName, hp.Spec.Name, humioapi.EntityNotFound{}) } func (h *MockClientConfig) UpdateParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) (*humioapi.Parser, error) { - return h.AddParser(config, req, hp) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), + searchDomainName: hp.Spec.RepositoryName, + resourceName: hp.Spec.Name, + } + + if _, found := h.apiClient.Parser[key]; !found { + return nil, fmt.Errorf("parser not found with name %s, err=%w", hp.Spec.Name, humioapi.EntityNotFound{}) + } + + value := ParserTransform(hp) + + h.apiClient.Parser[key] = *value + return value, nil } func (h *MockClientConfig) DeleteParser(config *humioapi.Config, req reconcile.Request, hp *humiov1alpha1.HumioParser) error { - h.apiClient.Parser = humioapi.Parser{} + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), + searchDomainName: hp.Spec.RepositoryName, + resourceName: hp.Spec.Name, + } + + delete(h.apiClient.Parser, key) return nil } func (h *MockClientConfig) AddRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { - h.apiClient.Repository = humioapi.Repository{ + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), + resourceName: hr.Spec.Name, + } + + if _, found := h.apiClient.Repository[key]; found { + return nil, fmt.Errorf("repository already exists with name %s", hr.Spec.Name) + } + + value := &humioapi.Repository{ ID: kubernetes.RandomString(), Name: hr.Spec.Name, Description: hr.Spec.Description, RetentionDays: float64(hr.Spec.Retention.TimeInDays), IngestRetentionSizeGB: float64(hr.Spec.Retention.IngestSizeInGB), StorageRetentionSizeGB: float64(hr.Spec.Retention.StorageSizeInGB), + AutomaticSearch: helpers.BoolTrue(hr.Spec.AutomaticSearch), } - return &h.apiClient.Repository, nil + + h.apiClient.Repository[key] = *value + return value, nil } func (h *MockClientConfig) GetRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { - h.apiClient.Repository.AutomaticSearch = helpers.BoolTrue(hr.Spec.AutomaticSearch) - return &h.apiClient.Repository, nil + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), + resourceName: hr.Spec.Name, + } + if value, found := h.apiClient.Repository[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find repository with name %s, err=%w", hr.Spec.Name, humioapi.EntityNotFound{}) + } func (h *MockClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { - return h.AddRepository(config, req, hr) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), + resourceName: hr.Spec.Name, + } + + if _, found := h.apiClient.Repository[key]; !found { + return nil, fmt.Errorf("repository not found with name %s, err=%w", hr.Spec.Name, humioapi.EntityNotFound{}) + } + + value := &humioapi.Repository{ + ID: kubernetes.RandomString(), + Name: hr.Spec.Name, + Description: hr.Spec.Description, + RetentionDays: float64(hr.Spec.Retention.TimeInDays), + IngestRetentionSizeGB: float64(hr.Spec.Retention.IngestSizeInGB), + StorageRetentionSizeGB: float64(hr.Spec.Retention.StorageSizeInGB), + AutomaticSearch: helpers.BoolTrue(hr.Spec.AutomaticSearch), + } + + h.apiClient.Repository[key] = *value + return value, nil } func (h *MockClientConfig) DeleteRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) error { - h.apiClient.Repository = humioapi.Repository{} + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), + resourceName: hr.Spec.Name, + } + + delete(h.apiClient.Repository, key) return nil } func (h *MockClientConfig) GetView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { - h.apiClient.View.AutomaticSearch = helpers.BoolTrue(hv.Spec.AutomaticSearch) - return &h.apiClient.View, nil + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), + resourceName: hv.Spec.Name, + } + if value, found := h.apiClient.View[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find view with name %s, err=%w", hv.Spec.Name, humioapi.EntityNotFound{}) } func (h *MockClientConfig) AddView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), + resourceName: hv.Spec.Name, + } + + if _, found := h.apiClient.Repository[key]; found { + return nil, fmt.Errorf("view already exists with name %s", hv.Spec.Name) + } + connections := make([]humioapi.ViewConnection, 0) for _, connection := range hv.Spec.Connections { connections = append(connections, humioapi.ViewConnection{ @@ -193,99 +371,252 @@ func (h *MockClientConfig) AddView(config *humioapi.Config, req reconcile.Reques }) } - h.apiClient.View = humioapi.View{ - Name: hv.Spec.Name, - Description: hv.Spec.Description, - Connections: connections, + value := &humioapi.View{ + Name: hv.Spec.Name, + Description: hv.Spec.Description, + Connections: connections, + AutomaticSearch: helpers.BoolTrue(hv.Spec.AutomaticSearch), } - return &h.apiClient.View, nil + h.apiClient.View[key] = *value + return value, nil } func (h *MockClientConfig) UpdateView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { - return h.AddView(config, req, hv) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), + resourceName: hv.Spec.Name, + } + + if _, found := h.apiClient.View[key]; !found { + return nil, fmt.Errorf("view not found with name %s, err=%w", hv.Spec.Name, humioapi.EntityNotFound{}) + } + + connections := make([]humioapi.ViewConnection, 0) + for _, connection := range hv.Spec.Connections { + connections = append(connections, humioapi.ViewConnection{ + RepoName: connection.RepositoryName, + Filter: connection.Filter, + }) + } + + value := &humioapi.View{ + Name: hv.Spec.Name, + Description: hv.Spec.Description, + Connections: connections, + AutomaticSearch: helpers.BoolTrue(hv.Spec.AutomaticSearch), + } + h.apiClient.View[key] = *value + return value, nil } func (h *MockClientConfig) DeleteView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) error { - h.apiClient.View = humioapi.View{} + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), + resourceName: hv.Spec.Name, + } + + delete(h.apiClient.View, key) return nil } func (h *MockClientConfig) GetLicense(config *humioapi.Config, req reconcile.Request) (humioapi.License, error) { - emptyOnPremLicense := humioapi.OnPremLicense{} + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), + } + + if value, found := h.apiClient.OnPremLicense[key]; found { + return &value, nil - if !reflect.DeepEqual(h.apiClient.OnPremLicense, emptyOnPremLicense) { - return h.apiClient.OnPremLicense, nil } - // by default, humio starts without a license - return emptyOnPremLicense, nil + return humioapi.OnPremLicense{}, nil } func (h *MockClientConfig) InstallLicense(config *humioapi.Config, req reconcile.Request, licenseString string) error { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + resourceName: fmt.Sprintf("%s%s", req.Namespace, req.Name), + } + onPremLicense, err := ParseLicenseType(licenseString) if err != nil { return fmt.Errorf("failed to parse license type: %w", err) } - if onPremLicense != nil { - h.apiClient.OnPremLicense = *onPremLicense - } - + h.apiClient.OnPremLicense[key] = *onPremLicense return nil } func (h *MockClientConfig) GetAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - if h.apiClient.Action.Name == "" { - return nil, fmt.Errorf("could not find action in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, } + if value, found := h.apiClient.Action[key]; found { + return &value, nil - return &h.apiClient.Action, nil + } + return nil, fmt.Errorf("could not find action in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) } func (h *MockClientConfig) AddAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + if _, found := h.apiClient.Action[key]; found { + return nil, fmt.Errorf("action already exists with name %s", ha.Spec.Name) + } + action, err := ActionFromActionCR(ha) if err != nil { - return action, err + return nil, err } - h.apiClient.Action = *action - return &h.apiClient.Action, nil + action.ID = kubernetes.RandomString() + + h.apiClient.Action[key] = *action + return action, nil } func (h *MockClientConfig) UpdateAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - return h.AddAction(config, req, ha) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + currentAction, found := h.apiClient.Action[key] + + if !found { + return nil, fmt.Errorf("could not find action in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) + } + + action, err := ActionFromActionCR(ha) + if err != nil { + return nil, err + } + action.ID = currentAction.ID + + h.apiClient.Action[key] = *action + return action, nil } func (h *MockClientConfig) DeleteAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) error { - h.apiClient.Action = humioapi.Action{} + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + delete(h.apiClient.Action, key) return nil } func (h *MockClientConfig) GetAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - if h.apiClient.Alert.Name == "" { - return nil, fmt.Errorf("could not find alert in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + if value, found := h.apiClient.Alert[key]; found { + return &value, nil + } - return &h.apiClient.Alert, nil + return nil, fmt.Errorf("could not find alert in view %q with name %q, err=%w", ha.Spec.ViewName, ha.Spec.Name, humioapi.EntityNotFound{}) } func (h *MockClientConfig) AddAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - actionIdMap, err := h.GetActionIDsMapForAlerts(config, req, ha) - if err != nil { - return &humioapi.Alert{}, fmt.Errorf("could not get action id mapping: %w", err) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + if _, found := h.apiClient.Alert[key]; found { + return nil, fmt.Errorf("alert already exists with name %s", ha.Spec.Name) } - alert, err := AlertTransform(ha, actionIdMap) + actionIdMap, err := h.GetActionIDsMapForAlerts(config, req, ha) if err != nil { - return alert, err + return nil, fmt.Errorf("could not get action id mapping: %w", err) } - h.apiClient.Alert = *alert - return &h.apiClient.Alert, nil + + value := AlertTransform(ha, actionIdMap) + value.ID = kubernetes.RandomString() + + h.apiClient.Alert[key] = *value + return value, nil } func (h *MockClientConfig) UpdateAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - return h.AddAlert(config, req, ha) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + currentAlert, found := h.apiClient.Alert[key] + + if !found { + return nil, fmt.Errorf("alert not found with name %s, err=%w", ha.Spec.Name, humioapi.EntityNotFound{}) + } + actionIdMap, err := h.GetActionIDsMapForAlerts(config, req, ha) + if err != nil { + return nil, fmt.Errorf("could not get action id mapping: %w", err) + } + + value := AlertTransform(ha, actionIdMap) + value.ID = currentAlert.ID + + h.apiClient.Alert[key] = *value + return value, nil } func (h *MockClientConfig) DeleteAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) error { - h.apiClient.Alert = humioapi.Alert{} + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + searchDomainName: ha.Spec.ViewName, + resourceName: ha.Spec.Name, + } + + delete(h.apiClient.Alert, key) return nil } @@ -299,30 +630,82 @@ func (h *MockClientConfig) GetActionIDsMapForAlerts(config *humioapi.Config, req } func (h *MockClientConfig) GetFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - if h.apiClient.FilterAlert.Name == "" { - return nil, fmt.Errorf("could not find alert in view %q with name %q, err=%w", hfa.Spec.ViewName, hfa.Spec.Name, humioapi.EntityNotFound{}) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), + searchDomainName: hfa.Spec.ViewName, + resourceName: hfa.Spec.Name, } - return &h.apiClient.FilterAlert, nil + if value, found := h.apiClient.FilterAlert[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find alert in view %q with name %q, err=%w", hfa.Spec.ViewName, hfa.Spec.Name, humioapi.EntityNotFound{}) } func (h *MockClientConfig) AddFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - if err := h.ValidateActionsForFilterAlert(config, req, hfa); err != nil { - return &humioapi.FilterAlert{}, fmt.Errorf("could not get action id mapping: %w", err) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), + searchDomainName: hfa.Spec.ViewName, + resourceName: hfa.Spec.Name, } - filterAlert, err := FilterAlertTransform(hfa) - if err != nil { - return filterAlert, err + + if _, found := h.apiClient.FilterAlert[key]; found { + return nil, fmt.Errorf("filter alert already exists with name %s", hfa.Spec.Name) } - h.apiClient.FilterAlert = *filterAlert - return &h.apiClient.FilterAlert, nil + if err := h.ValidateActionsForFilterAlert(config, req, hfa); err != nil { + return nil, fmt.Errorf("could not get action id mapping: %w", err) + } + + value := FilterAlertTransform(hfa) + value.ID = kubernetes.RandomString() + + h.apiClient.FilterAlert[key] = *value + return value, nil } func (h *MockClientConfig) UpdateFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - return h.AddFilterAlert(config, req, hfa) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), + searchDomainName: hfa.Spec.ViewName, + resourceName: hfa.Spec.Name, + } + + currentFilterAlert, found := h.apiClient.FilterAlert[key] + + if !found { + return nil, fmt.Errorf("could not find filter alert in view %q with name %q, err=%w", hfa.Spec.ViewName, hfa.Spec.Name, humioapi.EntityNotFound{}) + } + if err := h.ValidateActionsForFilterAlert(config, req, hfa); err != nil { + return nil, fmt.Errorf("could not get action id mapping: %w", err) + } + + value := FilterAlertTransform(hfa) + value.ID = currentFilterAlert.ID + + h.apiClient.FilterAlert[key] = *value + return value, nil } func (h *MockClientConfig) DeleteFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) error { - h.apiClient.FilterAlert = humioapi.FilterAlert{} + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), + searchDomainName: hfa.Spec.ViewName, + resourceName: hfa.Spec.Name, + } + + delete(h.apiClient.FilterAlert, key) return nil } @@ -331,30 +714,82 @@ func (h *MockClientConfig) ValidateActionsForFilterAlert(config *humioapi.Config } func (h *MockClientConfig) GetAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - if h.apiClient.AggregateAlert.Name == "" { - return nil, fmt.Errorf("could not find aggregate alert in view %q with name %q, err=%w", haa.Spec.ViewName, haa.Spec.Name, humioapi.EntityNotFound{}) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), + searchDomainName: haa.Spec.ViewName, + resourceName: haa.Spec.Name, } - return &h.apiClient.AggregateAlert, nil + if value, found := h.apiClient.AggregateAlert[key]; found { + return &value, nil + + } + return nil, fmt.Errorf("could not find aggregate alert in view %q with name %q, err=%w", haa.Spec.ViewName, haa.Spec.Name, humioapi.EntityNotFound{}) } func (h *MockClientConfig) AddAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - if err := h.ValidateActionsForAggregateAlert(config, req, haa); err != nil { - return &humioapi.AggregateAlert{}, fmt.Errorf("could not get action id mapping: %w", err) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), + searchDomainName: haa.Spec.ViewName, + resourceName: haa.Spec.Name, } - aggregateAlert, err := AggregateAlertTransform(haa) - if err != nil { - return aggregateAlert, err + + if _, found := h.apiClient.AggregateAlert[key]; found { + return nil, fmt.Errorf("aggregate alert already exists with name %s", haa.Spec.Name) + } + if err := h.ValidateActionsForAggregateAlert(config, req, haa); err != nil { + return nil, fmt.Errorf("could not get action id mapping: %w", err) } - h.apiClient.AggregateAlert = *aggregateAlert - return &h.apiClient.AggregateAlert, nil + + value := AggregateAlertTransform(haa) + value.ID = kubernetes.RandomString() + + h.apiClient.AggregateAlert[key] = *value + return value, nil } func (h *MockClientConfig) UpdateAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - return h.AddAggregateAlert(config, req, haa) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), + searchDomainName: haa.Spec.ViewName, + resourceName: haa.Spec.Name, + } + + currentAggregateAlert, found := h.apiClient.AggregateAlert[key] + + if !found { + return nil, fmt.Errorf("could not find aggregate alert in view %q with name %q, err=%w", haa.Spec.ViewName, haa.Spec.Name, humioapi.EntityNotFound{}) + } + if err := h.ValidateActionsForAggregateAlert(config, req, haa); err != nil { + return nil, fmt.Errorf("could not get action id mapping: %w", err) + } + + value := AggregateAlertTransform(haa) + value.ID = currentAggregateAlert.ID + + h.apiClient.AggregateAlert[key] = *value + return value, nil } func (h *MockClientConfig) DeleteAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) error { - h.apiClient.AggregateAlert = humioapi.AggregateAlert{} + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", haa.Spec.ManagedClusterName, haa.Spec.ExternalClusterName), + searchDomainName: haa.Spec.ViewName, + resourceName: haa.Spec.Name, + } + + delete(h.apiClient.AggregateAlert, key) return nil } @@ -363,30 +798,82 @@ func (h *MockClientConfig) ValidateActionsForAggregateAlert(config *humioapi.Con } func (h *MockClientConfig) AddScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - if err := h.ValidateActionsForScheduledSearch(config, req, hss); err != nil { - return &humioapi.ScheduledSearch{}, fmt.Errorf("could not get action id mapping: %w", err) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), + searchDomainName: hss.Spec.ViewName, + resourceName: hss.Spec.Name, } - scheduledSearch, err := ScheduledSearchTransform(hss) - if err != nil { - return scheduledSearch, err + + if _, found := h.apiClient.ScheduledSearch[key]; found { + return nil, fmt.Errorf("scheduled search already exists with name %s", hss.Spec.Name) + } + if err := h.ValidateActionsForScheduledSearch(config, req, hss); err != nil { + return nil, fmt.Errorf("could not get action id mapping: %w", err) } - h.apiClient.ScheduledSearch = *scheduledSearch - return &h.apiClient.ScheduledSearch, nil + + value := ScheduledSearchTransform(hss) + value.ID = kubernetes.RandomString() + + h.apiClient.ScheduledSearch[key] = *value + return value, nil } func (h *MockClientConfig) GetScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - if h.apiClient.ScheduledSearch.Name == "" { - return nil, fmt.Errorf("could not find scheduled search in view %q with name %q, err=%w", hss.Spec.ViewName, hss.Spec.Name, humioapi.EntityNotFound{}) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), + searchDomainName: hss.Spec.ViewName, + resourceName: hss.Spec.Name, + } + if value, found := h.apiClient.ScheduledSearch[key]; found { + return &value, nil + } - return &h.apiClient.ScheduledSearch, nil + return nil, fmt.Errorf("could not find scheduled search in view %q with name %q, err=%w", hss.Spec.ViewName, hss.Spec.Name, humioapi.EntityNotFound{}) } func (h *MockClientConfig) UpdateScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - return h.AddScheduledSearch(config, req, hss) + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), + searchDomainName: hss.Spec.ViewName, + resourceName: hss.Spec.Name, + } + + currentScheduledSearch, found := h.apiClient.ScheduledSearch[key] + + if !found { + return nil, fmt.Errorf("could not find scheduled search in view %q with name %q, err=%w", hss.Spec.ViewName, hss.Spec.Name, humioapi.EntityNotFound{}) + } + if err := h.ValidateActionsForScheduledSearch(config, req, hss); err != nil { + return nil, fmt.Errorf("could not get action id mapping: %w", err) + } + + value := ScheduledSearchTransform(hss) + value.ID = currentScheduledSearch.ID + + h.apiClient.ScheduledSearch[key] = *value + return value, nil } func (h *MockClientConfig) DeleteScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) error { - h.apiClient.ScheduledSearch = humioapi.ScheduledSearch{} + humioClientMu.Lock() + defer humioClientMu.Unlock() + + key := resourceKey{ + clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), + searchDomainName: hss.Spec.ViewName, + resourceName: hss.Spec.Name, + } + + delete(h.apiClient.ScheduledSearch, key) return nil } @@ -400,14 +887,17 @@ func (h *MockClientConfig) GetHumioClient(config *humioapi.Config, req ctrl.Requ } func (h *MockClientConfig) ClearHumioClientConnections() { - h.apiClient.IngestToken = humioapi.IngestToken{} - h.apiClient.Parser = humioapi.Parser{} - h.apiClient.Repository = humioapi.Repository{} - h.apiClient.View = humioapi.View{} - h.apiClient.OnPremLicense = humioapi.OnPremLicense{} - h.apiClient.Action = humioapi.Action{} - h.apiClient.Alert = humioapi.Alert{} - h.apiClient.FilterAlert = humioapi.FilterAlert{} - h.apiClient.AggregateAlert = humioapi.AggregateAlert{} - h.apiClient.ScheduledSearch = humioapi.ScheduledSearch{} + // TODO: Find out if we can rip this function out entirely. Maybe tests should be updated to include object deletions? + h.apiClient.OnPremLicense = make(map[resourceKey]humioapi.OnPremLicense) + + h.apiClient.Repository = make(map[resourceKey]humioapi.Repository) + h.apiClient.View = make(map[resourceKey]humioapi.View) + + h.apiClient.IngestToken = make(map[resourceKey]humioapi.IngestToken) + h.apiClient.Parser = make(map[resourceKey]humioapi.Parser) + h.apiClient.Action = make(map[resourceKey]humioapi.Action) + h.apiClient.Alert = make(map[resourceKey]humioapi.Alert) + h.apiClient.FilterAlert = make(map[resourceKey]humioapi.FilterAlert) + h.apiClient.AggregateAlert = make(map[resourceKey]humioapi.AggregateAlert) + h.apiClient.ScheduledSearch = make(map[resourceKey]humioapi.ScheduledSearch) } diff --git a/pkg/humio/filteralert_transform.go b/pkg/humio/filteralert_transform.go index 543f173c..00c90dfa 100644 --- a/pkg/humio/filteralert_transform.go +++ b/pkg/humio/filteralert_transform.go @@ -3,14 +3,9 @@ package humio import ( humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const ( - FilterAlertIdentifierAnnotation = "humio.com/filter-alert-id" -) - -func FilterAlertTransform(hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { +func FilterAlertTransform(hfa *humiov1alpha1.HumioFilterAlert) *humioapi.FilterAlert { filterAlert := &humioapi.FilterAlert{ Name: hfa.Spec.Name, QueryString: hfa.Spec.QueryString, @@ -23,14 +18,14 @@ func FilterAlertTransform(hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.Filter QueryOwnershipType: humioapi.QueryOwnershipTypeOrganization, } - if _, ok := hfa.ObjectMeta.Annotations[FilterAlertIdentifierAnnotation]; ok { - filterAlert.ID = hfa.ObjectMeta.Annotations[FilterAlertIdentifierAnnotation] + if filterAlert.Labels == nil { + filterAlert.Labels = []string{} } - return filterAlert, nil + return filterAlert } -func FilterAlertHydrate(hfa *humiov1alpha1.HumioFilterAlert, alert *humioapi.FilterAlert) error { +func FilterAlertHydrate(hfa *humiov1alpha1.HumioFilterAlert, alert *humioapi.FilterAlert) { hfa.Spec = humiov1alpha1.HumioFilterAlertSpec{ Name: alert.Name, QueryString: alert.QueryString, @@ -41,12 +36,4 @@ func FilterAlertHydrate(hfa *humiov1alpha1.HumioFilterAlert, alert *humioapi.Fil Actions: alert.ActionNames, Labels: alert.Labels, } - - hfa.ObjectMeta = metav1.ObjectMeta{ - Annotations: map[string]string{ - FilterAlertIdentifierAnnotation: alert.ID, - }, - } - - return nil } diff --git a/pkg/humio/ingesttoken_transform.go b/pkg/humio/ingesttoken_transform.go new file mode 100644 index 00000000..35ac2126 --- /dev/null +++ b/pkg/humio/ingesttoken_transform.go @@ -0,0 +1,15 @@ +package humio + +import ( + humioapi "github.com/humio/cli/api" + humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" +) + +func IngestTokenTransform(hit *humiov1alpha1.HumioIngestToken) *humioapi.IngestToken { + ingestToken := &humioapi.IngestToken{ + Name: hit.Spec.Name, + AssignedParser: hit.Spec.ParserName, + } + + return ingestToken +} diff --git a/pkg/humio/parser_transform.go b/pkg/humio/parser_transform.go new file mode 100644 index 00000000..e6a603fa --- /dev/null +++ b/pkg/humio/parser_transform.go @@ -0,0 +1,26 @@ +package humio + +import ( + humioapi "github.com/humio/cli/api" + humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" +) + +func ParserTransform(hp *humiov1alpha1.HumioParser) *humioapi.Parser { + parser := &humioapi.Parser{ + Name: hp.Spec.Name, + Script: hp.Spec.ParserScript, + FieldsToTag: hp.Spec.TagFields, + FieldsToBeRemovedBeforeParsing: []string{}, + } + + testCasesGQL := make([]humioapi.ParserTestCase, len(hp.Spec.TestData)) + for i := range hp.Spec.TestData { + testCasesGQL[i] = humioapi.ParserTestCase{ + Event: humioapi.ParserTestEvent{RawString: hp.Spec.TestData[i]}, + Assertions: []humioapi.ParserTestCaseAssertions{}, + } + } + parser.TestCases = testCasesGQL + + return parser +} diff --git a/pkg/humio/scheduledsearch_transform.go b/pkg/humio/scheduledsearch_transform.go index b56100e5..d8d3d177 100644 --- a/pkg/humio/scheduledsearch_transform.go +++ b/pkg/humio/scheduledsearch_transform.go @@ -3,14 +3,9 @@ package humio import ( humioapi "github.com/humio/cli/api" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -const ( - ScheduledSearchIdentifierAnnotation = "humio.com/scheduled-search-id" -) - -func ScheduledSearchTransform(hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { +func ScheduledSearchTransform(hss *humiov1alpha1.HumioScheduledSearch) *humioapi.ScheduledSearch { scheduledSearch := &humioapi.ScheduledSearch{ Name: hss.Spec.Name, QueryString: hss.Spec.QueryString, @@ -26,18 +21,14 @@ func ScheduledSearchTransform(hss *humiov1alpha1.HumioScheduledSearch) (*humioap QueryOwnershipType: humioapi.QueryOwnershipTypeOrganization, } - if _, ok := hss.ObjectMeta.Annotations[ScheduledSearchIdentifierAnnotation]; ok { - scheduledSearch.ID = hss.ObjectMeta.Annotations[ScheduledSearchIdentifierAnnotation] - } - if scheduledSearch.Labels == nil { scheduledSearch.Labels = []string{} } - return scheduledSearch, nil + return scheduledSearch } -func ScheduledSearchHydrate(hss *humiov1alpha1.HumioScheduledSearch, scheduledSearch *humioapi.ScheduledSearch) error { +func ScheduledSearchHydrate(hss *humiov1alpha1.HumioScheduledSearch, scheduledSearch *humioapi.ScheduledSearch) { hss.Spec = humiov1alpha1.HumioScheduledSearchSpec{ Name: scheduledSearch.Name, QueryString: scheduledSearch.QueryString, @@ -52,11 +43,5 @@ func ScheduledSearchHydrate(hss *humiov1alpha1.HumioScheduledSearch, scheduledSe Labels: scheduledSearch.Labels, } - hss.ObjectMeta = metav1.ObjectMeta{ - Annotations: map[string]string{ - ScheduledSearchIdentifierAnnotation: scheduledSearch.ID, - }, - } - - return nil + return } From 4732735624c37a38cb1f1b86806bc9c3e9ca1050 Mon Sep 17 00:00:00 2001 From: Mike Rostermund Date: Wed, 14 Aug 2024 14:18:57 +0200 Subject: [PATCH 2/7] look up searchdomain instead view during entity creation --- .../clusters/humiocluster_controller_test.go | 4 +- .../humioresources_controller_test.go | 4 +- controllers/suite/resources/suite_test.go | 5 +- go.mod | 2 +- go.sum | 4 +- pkg/humio/alert_transform.go | 18 --- pkg/humio/client.go | 146 +++++------------- pkg/humio/client_mock.go | 96 ++++++++++-- pkg/humio/scheduledsearch_transform.go | 2 - 9 files changed, 128 insertions(+), 153 deletions(-) diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index 35a7bc17..ba82eaac 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -56,12 +56,12 @@ var _ = Describe("HumioCluster Controller", func() { BeforeEach(func() { // failed test runs that don't clean up leave resources behind. - testHumioClient.ClearHumioClientConnections() + testHumioClient.ClearHumioClientConnections("") }) AfterEach(func() { // Add any teardown steps that needs to be executed after each test - testHumioClient.ClearHumioClientConnections() + testHumioClient.ClearHumioClientConnections("") }) // Add Tests for OpenAPI validation (or additional CRD features) specified in diff --git a/controllers/suite/resources/humioresources_controller_test.go b/controllers/suite/resources/humioresources_controller_test.go index 0185b98b..c3d88029 100644 --- a/controllers/suite/resources/humioresources_controller_test.go +++ b/controllers/suite/resources/humioresources_controller_test.go @@ -43,12 +43,12 @@ import ( var _ = Describe("Humio Resources Controllers", func() { BeforeEach(func() { // failed test runs that don't clean up leave resources behind. - humioClient.ClearHumioClientConnections() + humioClient.ClearHumioClientConnections(testRepoName) }) AfterEach(func() { // Add any teardown steps that needs to be executed after each test - humioClient.ClearHumioClientConnections() + humioClient.ClearHumioClientConnections(testRepoName) }) // Add Tests for OpenAPI validation (or additional CRD features) specified in diff --git a/controllers/suite/resources/suite_test.go b/controllers/suite/resources/suite_test.go index 48d1a7c5..0c49cb58 100644 --- a/controllers/suite/resources/suite_test.go +++ b/controllers/suite/resources/suite_test.go @@ -68,6 +68,7 @@ var k8sManager ctrl.Manager var humioClient humio.Client var testTimeout time.Duration var testNamespace corev1.Namespace +var testRepoName = "test-repo" var testRepo corev1alpha1.HumioRepository var testService1 corev1.Service var testService2 corev1.Service @@ -267,12 +268,12 @@ var _ = BeforeSuite(func() { testRepo = corev1alpha1.HumioRepository{ ObjectMeta: metav1.ObjectMeta{ - Name: "test-repo", + Name: testRepoName, Namespace: clusterKey.Namespace, }, Spec: corev1alpha1.HumioRepositorySpec{ ManagedClusterName: clusterKey.Name, - Name: "test-repo", + Name: testRepoName, AllowDataDeletion: true, }, } diff --git a/go.mod b/go.mod index 557ed67a..b833a082 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/go-logr/logr v1.4.2 github.com/go-logr/zapr v1.3.0 github.com/google/go-cmp v0.6.0 - github.com/humio/cli v0.36.1-0.20240813114317-eafdd46e889a + github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce github.com/onsi/ginkgo/v2 v2.20.0 github.com/onsi/gomega v1.34.1 github.com/prometheus/client_golang v1.19.0 diff --git a/go.sum b/go.sum index f97a105c..78948ccb 100644 --- a/go.sum +++ b/go.sum @@ -52,8 +52,8 @@ github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQu github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/humio/cli v0.36.1-0.20240813114317-eafdd46e889a h1:1SegzWT5U+6xslFrJgRnMbMVnSkQj19a6tl5u+nRB+A= -github.com/humio/cli v0.36.1-0.20240813114317-eafdd46e889a/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= +github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce h1:WRVLad++Yerg08UcQCzAXY9UwV0P7U1lkOvrdMYUjVY= +github.com/humio/cli v0.36.1-0.20240814103929-aacdf44666ce/go.mod h1:Du1GCeQ65rVrUQX/ge45RFflX+I3ZLU3sdCM8kHpuq8= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= diff --git a/pkg/humio/alert_transform.go b/pkg/humio/alert_transform.go index 93bea446..4c71792a 100644 --- a/pkg/humio/alert_transform.go +++ b/pkg/humio/alert_transform.go @@ -25,24 +25,6 @@ func AlertTransform(ha *humiov1alpha1.HumioAlert, actionIdMap map[string]string) return alert } -func AlertHydrate(ha *humiov1alpha1.HumioAlert, alert *humioapi.Alert, actionIdMap map[string]string) { - ha.Spec = humiov1alpha1.HumioAlertSpec{ - Name: alert.Name, - Query: humiov1alpha1.HumioQuery{ - QueryString: alert.QueryString, - Start: alert.QueryStart, - }, - Description: alert.Description, - ThrottleTimeMillis: alert.ThrottleTimeMillis, - ThrottleField: alert.ThrottleField, - Silenced: !alert.Enabled, - Actions: actionIdsFromActionMap(ha.Spec.Actions, actionIdMap), - Labels: alert.Labels, - } - - return -} - func actionIdsFromActionMap(actionList []string, actionIdMap map[string]string) []string { var actionIds []string for _, action := range actionList { diff --git a/pkg/humio/client.go b/pkg/humio/client.go index f2e7eb93..4d5ece1b 100644 --- a/pkg/humio/client.go +++ b/pkg/humio/client.go @@ -53,10 +53,10 @@ type Client interface { type ClusterClient interface { GetClusters(*humioapi.Config, reconcile.Request) (humioapi.Cluster, error) GetHumioClient(*humioapi.Config, reconcile.Request) *humioapi.Client - ClearHumioClientConnections() + ClearHumioClientConnections(string) GetBaseURL(*humioapi.Config, reconcile.Request, *humiov1alpha1.HumioCluster) *url.URL TestAPIToken(*humioapi.Config, reconcile.Request) error - Status(*humioapi.Config, reconcile.Request) (humioapi.StatusResponse, error) + Status(*humioapi.Config, reconcile.Request) (*humioapi.StatusResponse, error) } type IngestTokensClient interface { @@ -213,7 +213,7 @@ func (h *ClientConfig) GetHumioClient(config *humioapi.Config, req ctrl.Request) return c.client } -func (h *ClientConfig) ClearHumioClientConnections() { +func (h *ClientConfig) ClearHumioClientConnections(string) { h.humioClientsMutex.Lock() defer h.humioClientsMutex.Unlock() @@ -221,22 +221,13 @@ func (h *ClientConfig) ClearHumioClientConnections() { } // Status returns the status of the humio cluster -func (h *ClientConfig) Status(config *humioapi.Config, req reconcile.Request) (humioapi.StatusResponse, error) { - status, err := h.GetHumioClient(config, req).Status() - if err != nil { - h.logger.Error(err, "could not get status") - return humioapi.StatusResponse{}, err - } - return *status, err +func (h *ClientConfig) Status(config *humioapi.Config, req reconcile.Request) (*humioapi.StatusResponse, error) { + return h.GetHumioClient(config, req).Status() } // GetClusters returns a humio cluster and can be mocked via the Client interface func (h *ClientConfig) GetClusters(config *humioapi.Config, req reconcile.Request) (humioapi.Cluster, error) { - clusters, err := h.GetHumioClient(config, req).Clusters().Get() - if err != nil { - h.logger.Error(err, "could not get cluster information") - } - return clusters, err + return h.GetHumioClient(config, req).Clusters().Get() } // GetBaseURL returns the base URL for given HumioCluster @@ -337,24 +328,17 @@ func (h *ClientConfig) AddRepository(config *humioapi.Config, req reconcile.Requ } func (h *ClientConfig) GetRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { - repoList, err := h.GetHumioClient(config, req).Repositories().List() + repo, err := h.GetHumioClient(config, req).Repositories().Get(hr.Spec.Name) if err != nil { - return &humioapi.Repository{}, fmt.Errorf("could not list repositories: %w", err) - } - for _, repo := range repoList { - if repo.Name == hr.Spec.Name { - // we now know the repository exists - repository, err := h.GetHumioClient(config, req).Repositories().Get(hr.Spec.Name) - return &repository, err - } + return nil, err } - return &humioapi.Repository{}, nil + return &repo, nil } func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.Request, hr *humiov1alpha1.HumioRepository) (*humioapi.Repository, error) { curRepository, err := h.GetRepository(config, req, hr) if err != nil { - return &humioapi.Repository{}, err + return nil, err } if curRepository.Description != hr.Spec.Description { @@ -363,7 +347,7 @@ func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.R hr.Spec.Description, ) if err != nil { - return &humioapi.Repository{}, err + return nil, err } } @@ -374,7 +358,7 @@ func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.R hr.Spec.AllowDataDeletion, ) if err != nil { - return &humioapi.Repository{}, err + return nil, err } } @@ -385,7 +369,7 @@ func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.R hr.Spec.AllowDataDeletion, ) if err != nil { - return &humioapi.Repository{}, err + return nil, err } } @@ -396,7 +380,7 @@ func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.R hr.Spec.AllowDataDeletion, ) if err != nil { - return &humioapi.Repository{}, err + return nil, err } } @@ -406,7 +390,7 @@ func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.R helpers.BoolTrue(hr.Spec.AutomaticSearch), ) if err != nil { - return &humioapi.Repository{}, err + return nil, err } } @@ -427,18 +411,7 @@ func (h *ClientConfig) DeleteRepository(config *humioapi.Config, req reconcile.R } func (h *ClientConfig) GetView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { - viewList, err := h.GetHumioClient(config, req).Views().List() - if err != nil { - return &humioapi.View{}, fmt.Errorf("could not list views: %w", err) - } - for _, v := range viewList { - if v.Name == hv.Spec.Name { - // we now know the view exists - view, err := h.GetHumioClient(config, req).Views().Get(hv.Spec.Name) - return view, err - } - } - return &humioapi.View{}, nil + return h.GetHumioClient(config, req).Views().Get(hv.Spec.Name) } func (h *ClientConfig) AddView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { @@ -458,7 +431,7 @@ func (h *ClientConfig) AddView(config *humioapi.Config, req reconcile.Request, h func (h *ClientConfig) UpdateView(config *humioapi.Config, req reconcile.Request, hv *humiov1alpha1.HumioView) (*humioapi.View, error) { curView, err := h.GetView(config, req, hv) if err != nil { - return &humioapi.View{}, err + return nil, err } if curView.Description != hv.Spec.Description { @@ -467,7 +440,7 @@ func (h *ClientConfig) UpdateView(config *humioapi.Config, req reconcile.Request hv.Spec.Description, ) if err != nil { - return &humioapi.View{}, err + return nil, err } } @@ -477,7 +450,7 @@ func (h *ClientConfig) UpdateView(config *humioapi.Config, req reconcile.Request helpers.BoolTrue(hv.Spec.AutomaticSearch), ) if err != nil { - return &humioapi.View{}, err + return nil, err } } @@ -491,7 +464,7 @@ func (h *ClientConfig) UpdateView(config *humioapi.Config, req reconcile.Request getConnectionMap(connections), ) if err != nil { - return &humioapi.View{}, err + return nil, err } return h.GetView(config, req, hv) @@ -505,46 +478,22 @@ func (h *ClientConfig) DeleteView(config *humioapi.Config, req reconcile.Request return h.GetHumioClient(config, req).Views().Delete(hv.Spec.Name, "Deleted by humio-operator") } -func (h *ClientConfig) validateView(config *humioapi.Config, req reconcile.Request, viewName string) error { - view := &humiov1alpha1.HumioView{ - Spec: humiov1alpha1.HumioViewSpec{ - Name: viewName, - }, - } - - viewResult, err := h.GetView(config, req, view) - if err != nil { - return fmt.Errorf("failed to verify view %s exists. error: %w", viewName, err) - } - - emptyView := &humioapi.View{} - if reflect.DeepEqual(emptyView, viewResult) { - return fmt.Errorf("view %s does not exist", viewName) - } - - return nil +func (h *ClientConfig) validateSearchDomain(config *humioapi.Config, req reconcile.Request, searchDomainName string) error { + _, err := h.GetHumioClient(config, req).SearchDomains().Get(searchDomainName) + return err } func (h *ClientConfig) GetAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - err := h.validateView(config, req, ha.Spec.ViewName) + err := h.validateSearchDomain(config, req, ha.Spec.ViewName) if err != nil { return nil, fmt.Errorf("problem getting view for action %s: %w", ha.Spec.Name, err) } - action, err := h.GetHumioClient(config, req).Actions().Get(ha.Spec.ViewName, ha.Spec.Name) - if err != nil { - return nil, fmt.Errorf("error when trying to get action %+v, name=%s, view=%s: %w", action, ha.Spec.Name, ha.Spec.ViewName, err) - } - - if action == nil || action.Name == "" { - return nil, nil - } - - return action, nil + return h.GetHumioClient(config, req).Actions().Get(ha.Spec.ViewName, ha.Spec.Name) } func (h *ClientConfig) AddAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - err := h.validateView(config, req, ha.Spec.ViewName) + err := h.validateSearchDomain(config, req, ha.Spec.ViewName) if err != nil { return nil, fmt.Errorf("problem getting view for action %s: %w", ha.Spec.Name, err) } @@ -562,7 +511,7 @@ func (h *ClientConfig) AddAction(config *humioapi.Config, req reconcile.Request, } func (h *ClientConfig) UpdateAction(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAction) (*humioapi.Action, error) { - err := h.validateView(config, req, ha.Spec.ViewName) + err := h.validateSearchDomain(config, req, ha.Spec.ViewName) if err != nil { return nil, fmt.Errorf("problem getting view for action %s: %w", ha.Spec.Name, err) } @@ -609,25 +558,16 @@ func (h *ClientConfig) InstallLicense(config *humioapi.Config, req reconcile.Req } func (h *ClientConfig) GetAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - err := h.validateView(config, req, ha.Spec.ViewName) + err := h.validateSearchDomain(config, req, ha.Spec.ViewName) if err != nil { return &humioapi.Alert{}, fmt.Errorf("problem getting view for alert %s: %w", ha.Spec.Name, err) } - alert, err := h.GetHumioClient(config, req).Alerts().Get(ha.Spec.ViewName, ha.Spec.Name) - if err != nil { - return alert, fmt.Errorf("error when trying to get alert %+v, name=%s, view=%s: %w", alert, ha.Spec.Name, ha.Spec.ViewName, err) - } - - if alert == nil || alert.Name == "" { - return nil, nil - } - - return alert, nil + return h.GetHumioClient(config, req).Alerts().Get(ha.Spec.ViewName, ha.Spec.Name) } func (h *ClientConfig) AddAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - err := h.validateView(config, req, ha.Spec.ViewName) + err := h.validateSearchDomain(config, req, ha.Spec.ViewName) if err != nil { return &humioapi.Alert{}, fmt.Errorf("problem getting view for alert: %w", err) } @@ -646,7 +586,7 @@ func (h *ClientConfig) AddAlert(config *humioapi.Config, req reconcile.Request, } func (h *ClientConfig) UpdateAlert(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (*humioapi.Alert, error) { - err := h.validateView(config, req, ha.Spec.ViewName) + err := h.validateSearchDomain(config, req, ha.Spec.ViewName) if err != nil { return &humioapi.Alert{}, fmt.Errorf("problem getting view for action: %w", err) } @@ -675,7 +615,7 @@ func (h *ClientConfig) DeleteAlert(config *humioapi.Config, req reconcile.Reques } func (h *ClientConfig) GetFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - err := h.validateView(config, req, hfa.Spec.ViewName) + err := h.validateSearchDomain(config, req, hfa.Spec.ViewName) if err != nil { return &humioapi.FilterAlert{}, fmt.Errorf("problem getting view for filter alert %s: %w", hfa.Spec.Name, err) } @@ -706,7 +646,7 @@ func (h *ClientConfig) GetFilterAlert(config *humioapi.Config, req reconcile.Req } func (h *ClientConfig) AddFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - err := h.validateView(config, req, hfa.Spec.ViewName) + err := h.validateSearchDomain(config, req, hfa.Spec.ViewName) if err != nil { return &humioapi.FilterAlert{}, fmt.Errorf("problem getting view for filter alert: %w", err) } @@ -723,7 +663,7 @@ func (h *ClientConfig) AddFilterAlert(config *humioapi.Config, req reconcile.Req } func (h *ClientConfig) UpdateFilterAlert(config *humioapi.Config, req reconcile.Request, hfa *humiov1alpha1.HumioFilterAlert) (*humioapi.FilterAlert, error) { - err := h.validateView(config, req, hfa.Spec.ViewName) + err := h.validateSearchDomain(config, req, hfa.Spec.ViewName) if err != nil { return &humioapi.FilterAlert{}, fmt.Errorf("problem getting view for action: %w", err) } @@ -753,7 +693,7 @@ func (h *ClientConfig) DeleteFilterAlert(config *humioapi.Config, req reconcile. } func (h *ClientConfig) AddScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - err := h.validateView(config, req, hss.Spec.ViewName) + err := h.validateSearchDomain(config, req, hss.Spec.ViewName) if err != nil { return &humioapi.ScheduledSearch{}, fmt.Errorf("problem getting view for scheduled search: %w", err) } @@ -770,7 +710,7 @@ func (h *ClientConfig) AddScheduledSearch(config *humioapi.Config, req reconcile } func (h *ClientConfig) GetScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - err := h.validateView(config, req, hss.Spec.ViewName) + err := h.validateSearchDomain(config, req, hss.Spec.ViewName) if err != nil { return &humioapi.ScheduledSearch{}, fmt.Errorf("problem getting view for scheduled search %s: %w", hss.Spec.Name, err) } @@ -801,7 +741,7 @@ func (h *ClientConfig) GetScheduledSearch(config *humioapi.Config, req reconcile } func (h *ClientConfig) UpdateScheduledSearch(config *humioapi.Config, req reconcile.Request, hss *humiov1alpha1.HumioScheduledSearch) (*humioapi.ScheduledSearch, error) { - err := h.validateView(config, req, hss.Spec.ViewName) + err := h.validateSearchDomain(config, req, hss.Spec.ViewName) if err != nil { return &humioapi.ScheduledSearch{}, fmt.Errorf("problem getting view for scheduled search: %w", err) } @@ -838,17 +778,7 @@ func (h *ClientConfig) getAndValidateAction(config *humioapi.Config, req reconci }, } - actionResult, err := h.GetAction(config, req, action) - if err != nil { - return actionResult, fmt.Errorf("failed to verify action %s exists. error: %w", actionName, err) - } - - emptyAction := &humioapi.Action{} - if reflect.DeepEqual(emptyAction, actionResult) { - return actionResult, fmt.Errorf("action %s does not exist", actionName) - } - - return actionResult, nil + return h.GetAction(config, req, action) } func (h *ClientConfig) GetActionIDsMapForAlerts(config *humioapi.Config, req reconcile.Request, ha *humiov1alpha1.HumioAlert) (map[string]string, error) { diff --git a/pkg/humio/client_mock.go b/pkg/humio/client_mock.go index 260c5c28..68f413e4 100644 --- a/pkg/humio/client_mock.go +++ b/pkg/humio/client_mock.go @@ -68,7 +68,7 @@ type MockClientConfig struct { func NewMockClient() *MockClientConfig { mockClientConfig := &MockClientConfig{ apiClient: &ClientMock{ - OnPremLicense: map[resourceKey]humioapi.OnPremLicense{}, + OnPremLicense: make(map[resourceKey]humioapi.OnPremLicense), Repository: make(map[resourceKey]humioapi.Repository), View: make(map[resourceKey]humioapi.View), @@ -86,8 +86,8 @@ func NewMockClient() *MockClientConfig { return mockClientConfig } -func (h *MockClientConfig) Status(config *humioapi.Config, req reconcile.Request) (humioapi.StatusResponse, error) { - return humioapi.StatusResponse{ +func (h *MockClientConfig) Status(config *humioapi.Config, req reconcile.Request) (*humioapi.StatusResponse, error) { + return &humioapi.StatusResponse{ Status: "OK", Version: "x.y.z", }, nil @@ -110,8 +110,13 @@ func (h *MockClientConfig) AddIngestToken(config *humioapi.Config, req reconcile humioClientMu.Lock() defer humioClientMu.Unlock() + clusterName := fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, hit.Spec.RepositoryName) { + return nil, fmt.Errorf("search domain name does not exist") + } + key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hit.Spec.ManagedClusterName, hit.Spec.ExternalClusterName), + clusterName: clusterName, searchDomainName: hit.Spec.RepositoryName, resourceName: hit.Spec.Name, } @@ -184,8 +189,13 @@ func (h *MockClientConfig) AddParser(config *humioapi.Config, req reconcile.Requ humioClientMu.Lock() defer humioClientMu.Unlock() + clusterName := fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, hp.Spec.RepositoryName) { + return nil, fmt.Errorf("search domain name does not exist") + } + key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hp.Spec.ManagedClusterName, hp.Spec.ExternalClusterName), + clusterName: clusterName, searchDomainName: hp.Spec.RepositoryName, resourceName: hp.Spec.Name, } @@ -256,8 +266,13 @@ func (h *MockClientConfig) AddRepository(config *humioapi.Config, req reconcile. humioClientMu.Lock() defer humioClientMu.Unlock() + clusterName := fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName) + if h.searchDomainNameExists(clusterName, hr.Spec.Name) { + return nil, fmt.Errorf("search domain name already in use") + } + key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), + clusterName: clusterName, resourceName: hr.Spec.Name, } @@ -326,6 +341,8 @@ func (h *MockClientConfig) DeleteRepository(config *humioapi.Config, req reconci humioClientMu.Lock() defer humioClientMu.Unlock() + // TODO: consider finding all entities referring to this searchDomainName and remove them as well + key := resourceKey{ clusterName: fmt.Sprintf("%s%s", hr.Spec.ManagedClusterName, hr.Spec.ExternalClusterName), resourceName: hr.Spec.Name, @@ -354,8 +371,13 @@ func (h *MockClientConfig) AddView(config *humioapi.Config, req reconcile.Reques humioClientMu.Lock() defer humioClientMu.Unlock() + clusterName := fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName) + if h.searchDomainNameExists(clusterName, hv.Spec.Name) { + return nil, fmt.Errorf("search domain name already in use") + } + key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), + clusterName: clusterName, resourceName: hv.Spec.Name, } @@ -416,6 +438,8 @@ func (h *MockClientConfig) DeleteView(config *humioapi.Config, req reconcile.Req humioClientMu.Lock() defer humioClientMu.Unlock() + // TODO: consider finding all entities referring to this searchDomainName and remove them as well + key := resourceKey{ clusterName: fmt.Sprintf("%s%s", hv.Spec.ManagedClusterName, hv.Spec.ExternalClusterName), resourceName: hv.Spec.Name, @@ -478,8 +502,13 @@ func (h *MockClientConfig) AddAction(config *humioapi.Config, req reconcile.Requ humioClientMu.Lock() defer humioClientMu.Unlock() + clusterName := fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, ha.Spec.ViewName) { + return nil, fmt.Errorf("search domain name does not exist") + } + key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + clusterName: clusterName, searchDomainName: ha.Spec.ViewName, resourceName: ha.Spec.Name, } @@ -558,8 +587,13 @@ func (h *MockClientConfig) AddAlert(config *humioapi.Config, req reconcile.Reque humioClientMu.Lock() defer humioClientMu.Unlock() + clusterName := fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, ha.Spec.ViewName) { + return nil, fmt.Errorf("search domain name does not exist") + } + key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", ha.Spec.ManagedClusterName, ha.Spec.ExternalClusterName), + clusterName: clusterName, searchDomainName: ha.Spec.ViewName, resourceName: ha.Spec.Name, } @@ -649,8 +683,13 @@ func (h *MockClientConfig) AddFilterAlert(config *humioapi.Config, req reconcile humioClientMu.Lock() defer humioClientMu.Unlock() + clusterName := fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, hfa.Spec.ViewName) { + return nil, fmt.Errorf("search domain name does not exist") + } + key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hfa.Spec.ManagedClusterName, hfa.Spec.ExternalClusterName), + clusterName: clusterName, searchDomainName: hfa.Spec.ViewName, resourceName: hfa.Spec.Name, } @@ -801,8 +840,13 @@ func (h *MockClientConfig) AddScheduledSearch(config *humioapi.Config, req recon humioClientMu.Lock() defer humioClientMu.Unlock() + clusterName := fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName) + if !h.searchDomainNameExists(clusterName, hss.Spec.ViewName) { + return nil, fmt.Errorf("search domain name does not exist") + } + key := resourceKey{ - clusterName: fmt.Sprintf("%s%s", hss.Spec.ManagedClusterName, hss.Spec.ExternalClusterName), + clusterName: clusterName, searchDomainName: hss.Spec.ViewName, resourceName: hss.Spec.Name, } @@ -886,11 +930,12 @@ func (h *MockClientConfig) GetHumioClient(config *humioapi.Config, req ctrl.Requ return humioapi.NewClient(humioapi.Config{Address: clusterURL}) } -func (h *MockClientConfig) ClearHumioClientConnections() { - // TODO: Find out if we can rip this function out entirely. Maybe tests should be updated to include object deletions? - h.apiClient.OnPremLicense = make(map[resourceKey]humioapi.OnPremLicense) - - h.apiClient.Repository = make(map[resourceKey]humioapi.Repository) +func (h *MockClientConfig) ClearHumioClientConnections(repoNameToKeep string) { + for k := range h.apiClient.Repository { + if k.resourceName != repoNameToKeep { + delete(h.apiClient.Repository, k) + } + } h.apiClient.View = make(map[resourceKey]humioapi.View) h.apiClient.IngestToken = make(map[resourceKey]humioapi.IngestToken) @@ -901,3 +946,22 @@ func (h *MockClientConfig) ClearHumioClientConnections() { h.apiClient.AggregateAlert = make(map[resourceKey]humioapi.AggregateAlert) h.apiClient.ScheduledSearch = make(map[resourceKey]humioapi.ScheduledSearch) } + +// searchDomainNameExists returns a boolean if either a repository or view exists with the given search domain name. +// It assumes the caller already holds the lock humioClientMu. +func (h *MockClientConfig) searchDomainNameExists(clusterName, searchDomainName string) bool { + key := resourceKey{ + clusterName: clusterName, + resourceName: searchDomainName, + } + + if _, found := h.apiClient.Repository[key]; found { + return true + } + + if _, found := h.apiClient.View[key]; found { + return true + } + + return false +} diff --git a/pkg/humio/scheduledsearch_transform.go b/pkg/humio/scheduledsearch_transform.go index d8d3d177..599af1f6 100644 --- a/pkg/humio/scheduledsearch_transform.go +++ b/pkg/humio/scheduledsearch_transform.go @@ -42,6 +42,4 @@ func ScheduledSearchHydrate(hss *humiov1alpha1.HumioScheduledSearch, scheduledSe Actions: scheduledSearch.ActionNames, Labels: scheduledSearch.Labels, } - - return } From 896849d52be69aa910bac68cfd529448d396629a Mon Sep 17 00:00:00 2001 From: Mike Rostermund Date: Wed, 14 Aug 2024 15:13:29 +0200 Subject: [PATCH 3/7] skip status update if we got error when fetching version --- controllers/humiocluster_controller.go | 1 + 1 file changed, 1 insertion(+) diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index 367939a9..b22dac86 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -318,6 +318,7 @@ func (r *HumioClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request status, err := humioClient.Status(cluster.Config(), req) if err != nil { r.Log.Error(err, "unable to get cluster status") + return } _, _ = r.updateStatus(ctx, r.Client.Status(), hc, opts.withVersion(status.Version)) } From 6615fd091b547c3201c5c0c246fad75b9c68b2aa Mon Sep 17 00:00:00 2001 From: Mike Rostermund Date: Wed, 14 Aug 2024 15:32:51 +0200 Subject: [PATCH 4/7] add logging --- controllers/suite/clusters/suite_test.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/controllers/suite/clusters/suite_test.go b/controllers/suite/clusters/suite_test.go index c4687ac3..f5211d17 100644 --- a/controllers/suite/clusters/suite_test.go +++ b/controllers/suite/clusters/suite_test.go @@ -349,7 +349,11 @@ func markPodAsPending(ctx context.Context, client client.Client, nodeID int, pod func podReadyCountByRevision(ctx context.Context, hnp *controllers.HumioNodePool, expectedPodRevision int, expectedReadyCount int) map[int]int { revisionToReadyCount := map[int]int{} - clusterPods, _ := kubernetes.ListPods(ctx, k8sClient, hnp.GetNamespace(), hnp.GetNodePoolLabels()) + clusterPods, err := kubernetes.ListPods(ctx, k8sClient, hnp.GetNamespace(), hnp.GetNodePoolLabels()) + if err != nil { + suite.UsingClusterBy(hnp.GetClusterName(), "podReadyCountByRevision | ERROR WHILE LISTING PODS IN") + return map[int]int{} + } for nodeID, pod := range clusterPods { revision, _ := strconv.Atoi(pod.Annotations[controllers.PodRevisionAnnotation]) if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { @@ -365,7 +369,11 @@ func podReadyCountByRevision(ctx context.Context, hnp *controllers.HumioNodePool } } else { if nodeID+1 <= expectedReadyCount { - _ = suite.MarkPodAsRunning(ctx, k8sClient, nodeID, pod, hnp.GetClusterName()) + suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("podReadyCountByRevision | marking pod %s as running", pod.Name)) + err = suite.MarkPodAsRunning(ctx, k8sClient, nodeID, pod, hnp.GetClusterName()) + if err != nil { + suite.UsingClusterBy(hnp.GetClusterName(), "podReadyCountByRevision | ERROR WHILE MARKING POD AS RUNNING") + } revisionToReadyCount[revision]++ } } @@ -431,6 +439,7 @@ func ensurePodsRollingRestart(ctx context.Context, hnp *controllers.HumioNodePoo for expectedReadyCount := 1; expectedReadyCount < hnp.GetNodeCount()+1; expectedReadyCount++ { Eventually(func() map[int]int { + suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("Ensuring replacement pods are ready one at a time expectedReadyCount=%d", expectedReadyCount)) return podReadyCountByRevision(ctx, hnp, expectedPodRevision, expectedReadyCount) }, testTimeout, suite.TestInterval).Should(HaveKeyWithValue(expectedPodRevision, expectedReadyCount)) } From 5c01a9fdd35436bf6ebec3d21e45d0a0fae643cc Mon Sep 17 00:00:00 2001 From: Mike Rostermund Date: Thu, 15 Aug 2024 14:24:26 +0200 Subject: [PATCH 5/7] Requeue after incrementHumioClusterPodRevision and refactor podReadyCountByRevision Requeue after incrementHumioClusterPodRevision fixes a bug where the operator could in some cases create a new pod using the old revision as it did not fetch the updated HumioCluster resource before creating new pods. Refactor podReadyCountByRevision to extract the logic for what pods to should be marked as running and ensures we update only the pods that match the expected pod revision as running, as any older pod revisions should already be handled during previous iterations. --- controllers/humiocluster_annotations.go | 2 +- controllers/humiocluster_controller.go | 9 ++- controllers/humiocluster_pod_status.go | 4 ++ controllers/humiocluster_pods.go | 17 +++-- controllers/suite/clusters/suite_test.go | 92 +++++++++++++++++------- controllers/suite/common.go | 12 ++-- 6 files changed, 92 insertions(+), 44 deletions(-) diff --git a/controllers/humiocluster_annotations.go b/controllers/humiocluster_annotations.go index 1a9fb9bd..3a5f51ef 100644 --- a/controllers/humiocluster_annotations.go +++ b/controllers/humiocluster_annotations.go @@ -32,7 +32,7 @@ import ( const ( certHashAnnotation = "humio.com/certificate-hash" - podHashAnnotation = "humio.com/pod-hash" + PodHashAnnotation = "humio.com/pod-hash" PodRevisionAnnotation = "humio.com/pod-revision" envVarSourceHashAnnotation = "humio.com/env-var-source-hash" pvcHashAnnotation = "humio_pvc_hash" diff --git a/controllers/humiocluster_controller.go b/controllers/humiocluster_controller.go index b22dac86..54e63dc7 100644 --- a/controllers/humiocluster_controller.go +++ b/controllers/humiocluster_controller.go @@ -260,7 +260,8 @@ func (r *HumioClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request if err != nil { opts.withMessage(err.Error()) } - return r.updateStatus(ctx, r.Client.Status(), hc, opts.withState(hc.Status.State)) + _, _ = r.updateStatus(ctx, r.Client.Status(), hc, opts.withState(hc.Status.State)) + return reconcile.Result{Requeue: true}, nil } } @@ -377,7 +378,7 @@ func (r *HumioClusterReconciler) nodePoolPodsReady(ctx context.Context, hc *humi if podsStatus.waitingOnPods() { r.Log.Info("waiting on pods, refusing to continue with reconciliation until all pods are ready") r.Log.Info(fmt.Sprintf("cluster state is %s. waitingOnPods=%v, "+ - "revisionsInSync=%v, podRevisisons=%v, podDeletionTimestampSet=%v, podNames=%v, expectedRunningPods=%v, "+ + "revisionsInSync=%v, podRevisions=%v, podDeletionTimestampSet=%v, podNames=%v, expectedRunningPods=%v, "+ "podsReady=%v, podsNotReady=%v", hc.Status.State, podsStatus.waitingOnPods(), podsStatus.podRevisionsInSync(), podsStatus.podRevisions, podsStatus.podDeletionTimestampSet, podsStatus.podNames, @@ -2045,6 +2046,7 @@ func (r *HumioClusterReconciler) ensureMismatchedPodsAreDeleted(ctx context.Cont return r.updateStatus(ctx, r.Client.Status(), hc, statusOptions(). withMessage(r.logErrorAndReturn(err, fmt.Sprintf("failed to increment pod revision to %d", revision)).Error())) } + return reconcile.Result{Requeue: true}, nil } if !desiredLifecycleState.WantsUpgrade() && desiredLifecycleState.WantsRestart() { if result, err := r.updateStatus(ctx, r.Client.Status(), hc, statusOptions(). @@ -2055,6 +2057,7 @@ func (r *HumioClusterReconciler) ensureMismatchedPodsAreDeleted(ctx context.Cont return r.updateStatus(ctx, r.Client.Status(), hc, statusOptions(). withMessage(r.logErrorAndReturn(err, fmt.Sprintf("failed to increment pod revision to %d", revision)).Error())) } + return reconcile.Result{Requeue: true}, nil } } if desiredLifecycleState.ShouldDeletePod() { @@ -2120,7 +2123,7 @@ func (r *HumioClusterReconciler) ensureMismatchedPodsAreDeleted(ctx context.Cont } r.Log.Info(fmt.Sprintf("cluster state is still %s. waitingOnPods=%v, podBeingDeleted=%v, "+ - "revisionsInSync=%v, podRevisisons=%v, podDeletionTimestampSet=%v, podNames=%v, podHumioVersions=%v, expectedRunningPods=%v, podsReady=%v, podsNotReady=%v", + "revisionsInSync=%v, podRevisions=%v, podDeletionTimestampSet=%v, podNames=%v, podHumioVersions=%v, expectedRunningPods=%v, podsReady=%v, podsNotReady=%v", hc.Status.State, podsStatus.waitingOnPods(), desiredLifecycleState.ShouldDeletePod(), podsStatus.podRevisionsInSync(), podsStatus.podRevisions, podsStatus.podDeletionTimestampSet, podsStatus.podNames, podsStatus.podImageVersions, podsStatus.expectedRunningPods, podsStatus.readyCount, podsStatus.notReadyCount)) diff --git a/controllers/humiocluster_pod_status.go b/controllers/humiocluster_pod_status.go index e183eabc..0f36b6d6 100644 --- a/controllers/humiocluster_pod_status.go +++ b/controllers/humiocluster_pod_status.go @@ -3,6 +3,7 @@ package controllers import ( "context" "fmt" + "sort" "strconv" humiov1alpha1 "github.com/humio/humio-operator/api/v1alpha1" @@ -39,6 +40,9 @@ func (r *HumioClusterReconciler) getPodsStatus(ctx context.Context, hc *humiov1a notReadyCount: len(foundPodList), expectedRunningPods: hnp.GetNodeCount(), } + sort.Slice(foundPodList, func(i, j int) bool { + return foundPodList[i].Name < foundPodList[j].Name + }) var podsReady, podsNotReady []string for _, pod := range foundPodList { podRevisionStr := pod.Annotations[PodRevisionAnnotation] diff --git a/controllers/humiocluster_pods.go b/controllers/humiocluster_pods.go index 4749bf9b..c7b837ad 100644 --- a/controllers/humiocluster_pods.go +++ b/controllers/humiocluster_pods.go @@ -793,7 +793,7 @@ func (r *HumioClusterReconciler) createPod(ctx context.Context, hc *humiov1alpha return &corev1.Pod{}, r.logErrorAndReturn(err, "could not set controller reference") } r.Log.Info(fmt.Sprintf("pod %s will use attachments %+v", pod.Name, attachments)) - pod.Annotations[podHashAnnotation] = podSpecAsSHA256(hnp, *pod) + pod.Annotations[PodHashAnnotation] = podSpecAsSHA256(hnp, *pod) if attachments.envVarSourceData != nil { b, err := json.Marshal(attachments.envVarSourceData) @@ -808,15 +808,14 @@ func (r *HumioClusterReconciler) createPod(ctx context.Context, hc *humiov1alpha } _, podRevision := hnp.GetHumioClusterNodePoolRevisionAnnotation() - r.Log.Info(fmt.Sprintf("setting pod %s revision to %d", pod.Name, podRevision)) r.setPodRevision(pod, podRevision) - r.Log.Info(fmt.Sprintf("creating pod %s", pod.Name)) + r.Log.Info(fmt.Sprintf("creating pod %s with revision %d", pod.Name, podRevision)) err = r.Create(ctx, pod) if err != nil { return &corev1.Pod{}, err } - r.Log.Info(fmt.Sprintf("successfully created pod %s", pod.Name)) + r.Log.Info(fmt.Sprintf("successfully created pod %s with revision %d", pod.Name, podRevision)) return pod, nil } @@ -828,7 +827,7 @@ func (r *HumioClusterReconciler) waitForNewPods(ctx context.Context, hnp *HumioN // revision that were still terminating when the new pod was created var expectedPodCount int for _, pod := range previousPodList { - if pod.Annotations[podHashAnnotation] == expectedPods[0].Annotations[podHashAnnotation] { + if pod.Annotations[PodHashAnnotation] == expectedPods[0].Annotations[PodHashAnnotation] { expectedPodCount++ } } @@ -843,7 +842,7 @@ func (r *HumioClusterReconciler) waitForNewPods(ctx context.Context, hnp *HumioN return err } for _, pod := range latestPodList { - if pod.Annotations[podHashAnnotation] == expectedPods[0].Annotations[podHashAnnotation] { + if pod.Annotations[PodHashAnnotation] == expectedPods[0].Annotations[PodHashAnnotation] { podsMatchingRevisionCount++ } } @@ -857,7 +856,7 @@ func (r *HumioClusterReconciler) waitForNewPods(ctx context.Context, hnp *HumioN } func (r *HumioClusterReconciler) podsMatch(hnp *HumioNodePool, pod corev1.Pod, desiredPod corev1.Pod) (bool, error) { - if _, ok := pod.Annotations[podHashAnnotation]; !ok { + if _, ok := pod.Annotations[PodHashAnnotation]; !ok { return false, fmt.Errorf("did not find annotation with pod hash") } if _, ok := pod.Annotations[PodRevisionAnnotation]; !ok { @@ -872,7 +871,7 @@ func (r *HumioClusterReconciler) podsMatch(hnp *HumioNodePool, pod corev1.Pod, d desiredPodHash := podSpecAsSHA256(hnp, desiredPod) _, existingPodRevision := hnp.GetHumioClusterNodePoolRevisionAnnotation() r.setPodRevision(&desiredPod, existingPodRevision) - if pod.Annotations[podHashAnnotation] == desiredPodHash { + if pod.Annotations[PodHashAnnotation] == desiredPodHash { specMatches = true } if pod.Annotations[PodRevisionAnnotation] == desiredPod.Annotations[PodRevisionAnnotation] { @@ -905,7 +904,7 @@ func (r *HumioClusterReconciler) podsMatch(hnp *HumioNodePool, pod corev1.Pod, d sanitizedDesiredPod := sanitizePod(hnp, desiredPodCopy) podSpecDiff := cmp.Diff(sanitizedCurrentPod.Spec, sanitizedDesiredPod.Spec) if !specMatches { - r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", podHashAnnotation, pod.Annotations[podHashAnnotation], desiredPodHash), "podSpecDiff", podSpecDiff) + r.Log.Info(fmt.Sprintf("pod annotation %s does not match desired pod: got %+v, expected %+v", PodHashAnnotation, pod.Annotations[PodHashAnnotation], desiredPodHash), "podSpecDiff", podSpecDiff) return false, nil } if !revisionMatches { diff --git a/controllers/suite/clusters/suite_test.go b/controllers/suite/clusters/suite_test.go index f5211d17..135051d1 100644 --- a/controllers/suite/clusters/suite_test.go +++ b/controllers/suite/clusters/suite_test.go @@ -112,6 +112,9 @@ var _ = BeforeSuite(func() { // testEnv.Start() sporadically fails with "unable to grab random port for serving webhooks on", so let's // retry a couple of times cfg, err = testEnv.Start() + if err != nil { + By(fmt.Sprintf("Got error trying to start testEnv, retrying... err=%v", err)) + } return err }, 30*time.Second, 5*time.Second).Should(Succeed()) Expect(cfg).NotTo(BeNil()) @@ -347,35 +350,70 @@ func markPodAsPending(ctx context.Context, client client.Client, nodeID int, pod return client.Status().Update(ctx, &pod) } -func podReadyCountByRevision(ctx context.Context, hnp *controllers.HumioNodePool, expectedPodRevision int, expectedReadyCount int) map[int]int { +func markPodsWithRevisionAsReady(ctx context.Context, hnp *controllers.HumioNodePool, podRevision int, desiredReadyPodCount int) { + if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { + return + } + foundPodList, _ := kubernetes.ListPods(ctx, k8sClient, hnp.GetNamespace(), hnp.GetNodePoolLabels()) + suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("Found %d pods", len(foundPodList))) + podListWithRevision := []corev1.Pod{} + for i := range foundPodList { + foundPodRevisionValue, _ := foundPodList[i].Annotations[controllers.PodRevisionAnnotation] + foundPodHash, _ := foundPodList[i].Annotations[controllers.PodHashAnnotation] + suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("Pod=%s revision=%s podHash=%s podIP=%s", foundPodList[i].Name, foundPodRevisionValue, foundPodHash, foundPodList[i].Status.PodIP)) + foundPodRevisionValueInt, _ := strconv.Atoi(foundPodRevisionValue) + if foundPodRevisionValueInt == podRevision { + podListWithRevision = append(podListWithRevision, foundPodList[i]) + } + } + suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("revision=%d, count=%d pods", podRevision, len(podListWithRevision))) + + readyWithRevision := 0 + for i := range podListWithRevision { + if podListWithRevision[i].Status.PodIP != "" { + readyWithRevision++ + } + } + suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("revision=%d, count=%d pods, readyWithRevision=%d", podRevision, len(podListWithRevision), readyWithRevision)) + + if readyWithRevision == desiredReadyPodCount { + suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("Got expected pod count %d with revision %d", readyWithRevision, podRevision)) + return + } + + for i := range podListWithRevision { + suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("Considering pod %s with podIP %s", podListWithRevision[i].Name, podListWithRevision[i].Status.PodIP)) + if podListWithRevision[i].Status.PodIP == "" { + err := suite.MarkPodAsRunning(ctx, k8sClient, podListWithRevision[i], hnp.GetClusterName()) + if err != nil { + suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("Got error while marking pod %s as running: %v", podListWithRevision[i].Name, err)) + } + break + } + } +} + +func podReadyCountByRevision(ctx context.Context, hnp *controllers.HumioNodePool, expectedPodRevision int) map[int]int { revisionToReadyCount := map[int]int{} clusterPods, err := kubernetes.ListPods(ctx, k8sClient, hnp.GetNamespace(), hnp.GetNodePoolLabels()) if err != nil { - suite.UsingClusterBy(hnp.GetClusterName(), "podReadyCountByRevision | ERROR WHILE LISTING PODS IN") - return map[int]int{} + suite.UsingClusterBy(hnp.GetClusterName(), "podReadyCountByRevision | Got error when listing pods") } - for nodeID, pod := range clusterPods { - revision, _ := strconv.Atoi(pod.Annotations[controllers.PodRevisionAnnotation]) - if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { - if pod.DeletionTimestamp == nil { - for _, condition := range pod.Status.Conditions { - if condition.Type == corev1.PodReady { - if condition.Status == corev1.ConditionTrue { - revisionToReadyCount[revision]++ - } + for _, pod := range clusterPods { + value, found := pod.Annotations[controllers.PodRevisionAnnotation] + if !found { + suite.UsingClusterBy(hnp.GetClusterName(), "podReadyCountByRevision | ERROR, pod found without revision annotation") + } + revision, _ := strconv.Atoi(value) + if pod.DeletionTimestamp == nil { + for _, condition := range pod.Status.Conditions { + if condition.Type == corev1.PodReady { + if condition.Status == corev1.ConditionTrue { + revisionToReadyCount[revision]++ } } } - } else { - if nodeID+1 <= expectedReadyCount { - suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("podReadyCountByRevision | marking pod %s as running", pod.Name)) - err = suite.MarkPodAsRunning(ctx, k8sClient, nodeID, pod, hnp.GetClusterName()) - if err != nil { - suite.UsingClusterBy(hnp.GetClusterName(), "podReadyCountByRevision | ERROR WHILE MARKING POD AS RUNNING") - } - revisionToReadyCount[revision]++ - } } } @@ -440,7 +478,8 @@ func ensurePodsRollingRestart(ctx context.Context, hnp *controllers.HumioNodePoo for expectedReadyCount := 1; expectedReadyCount < hnp.GetNodeCount()+1; expectedReadyCount++ { Eventually(func() map[int]int { suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("Ensuring replacement pods are ready one at a time expectedReadyCount=%d", expectedReadyCount)) - return podReadyCountByRevision(ctx, hnp, expectedPodRevision, expectedReadyCount) + markPodsWithRevisionAsReady(ctx, hnp, expectedPodRevision, expectedReadyCount) + return podReadyCountByRevision(ctx, hnp, expectedPodRevision) }, testTimeout, suite.TestInterval).Should(HaveKeyWithValue(expectedPodRevision, expectedReadyCount)) } } @@ -457,14 +496,16 @@ func ensurePodsGoPending(ctx context.Context, hnp *controllers.HumioNodePool, ex func ensurePodsTerminate(ctx context.Context, hnp *controllers.HumioNodePool, expectedPodRevision int) { suite.UsingClusterBy(hnp.GetClusterName(), "Ensuring all existing pods are terminated at the same time") Eventually(func() map[int]int { - numPodsReadyByRevision := podReadyCountByRevision(ctx, hnp, expectedPodRevision, 0) + markPodsWithRevisionAsReady(ctx, hnp, expectedPodRevision, 0) + numPodsReadyByRevision := podReadyCountByRevision(ctx, hnp, expectedPodRevision) suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("podsReadyCountByRevision() = %#+v", numPodsReadyByRevision)) return numPodsReadyByRevision }, testTimeout, suite.TestInterval).Should(HaveKeyWithValue(expectedPodRevision-1, 0)) suite.UsingClusterBy(hnp.GetClusterName(), "Ensuring replacement pods are not ready at the same time") Eventually(func() map[int]int { - numPodsReadyByRevision := podReadyCountByRevision(ctx, hnp, expectedPodRevision, 0) + markPodsWithRevisionAsReady(ctx, hnp, expectedPodRevision, 0) + numPodsReadyByRevision := podReadyCountByRevision(ctx, hnp, expectedPodRevision) suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("podsReadyCountByRevision() = %#+v", numPodsReadyByRevision)) return numPodsReadyByRevision }, testTimeout, suite.TestInterval).Should(HaveKeyWithValue(expectedPodRevision, 0)) @@ -476,7 +517,8 @@ func ensurePodsSimultaneousRestart(ctx context.Context, hnp *controllers.HumioNo suite.UsingClusterBy(hnp.GetClusterName(), "Ensuring all pods come back up after terminating") Eventually(func() map[int]int { - numPodsReadyByRevision := podReadyCountByRevision(ctx, hnp, expectedPodRevision, hnp.GetNodeCount()) + markPodsWithRevisionAsReady(ctx, hnp, expectedPodRevision, hnp.GetNodeCount()) + numPodsReadyByRevision := podReadyCountByRevision(ctx, hnp, expectedPodRevision) suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("podsReadyCountByRevision() = %#+v", numPodsReadyByRevision)) return numPodsReadyByRevision }, testTimeout, suite.TestInterval).Should(HaveKeyWithValue(expectedPodRevision, hnp.GetNodeCount())) diff --git a/controllers/suite/common.go b/controllers/suite/common.go index dfa0f6ca..b2e6cfa7 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -66,8 +66,8 @@ func MarkPodsAsRunning(ctx context.Context, client client.Client, pods []corev1. } UsingClusterBy(clusterName, "Simulating Humio container starts up and is marked Ready") - for nodeID, pod := range pods { - err := MarkPodAsRunning(ctx, client, nodeID, pod, clusterName) + for _, pod := range pods { + err := MarkPodAsRunning(ctx, client, pod, clusterName) if err != nil { return err } @@ -75,13 +75,13 @@ func MarkPodsAsRunning(ctx context.Context, client client.Client, pods []corev1. return nil } -func MarkPodAsRunning(ctx context.Context, client client.Client, nodeID int, pod corev1.Pod, clusterName string) error { +func MarkPodAsRunning(ctx context.Context, k8sClient client.Client, pod corev1.Pod, clusterName string) error { if os.Getenv("TEST_USE_EXISTING_CLUSTER") == "true" { return nil } - UsingClusterBy(clusterName, fmt.Sprintf("Simulating Humio container starts up and is marked Ready (node %d, pod phase %s)", nodeID, pod.Status.Phase)) - pod.Status.PodIP = fmt.Sprintf("192.168.0.%d", nodeID) + UsingClusterBy(clusterName, fmt.Sprintf("Simulating Humio container starts up and is marked Ready (pod phase %s)", pod.Status.Phase)) + pod.Status.PodIP = fmt.Sprintf("192.168.0.1") pod.Status.Conditions = []corev1.PodCondition{ { Type: corev1.PodReady, @@ -89,7 +89,7 @@ func MarkPodAsRunning(ctx context.Context, client client.Client, nodeID int, pod }, } pod.Status.Phase = corev1.PodRunning - return client.Status().Update(ctx, &pod) + return k8sClient.Status().Update(ctx, &pod) } func CleanupCluster(ctx context.Context, k8sClient client.Client, hc *humiov1alpha1.HumioCluster) { From 196f21388e92831479a62fb1b8f049d2c78a603a Mon Sep 17 00:00:00 2001 From: Mike Rostermund Date: Thu, 15 Aug 2024 14:33:30 +0200 Subject: [PATCH 6/7] fix staticcheck --- controllers/suite/clusters/humiocluster_controller_test.go | 2 ++ controllers/suite/clusters/suite_test.go | 4 ++-- controllers/suite/common.go | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/controllers/suite/clusters/humiocluster_controller_test.go b/controllers/suite/clusters/humiocluster_controller_test.go index ba82eaac..920414d5 100644 --- a/controllers/suite/clusters/humiocluster_controller_test.go +++ b/controllers/suite/clusters/humiocluster_controller_test.go @@ -1141,8 +1141,10 @@ var _ = Describe("HumioCluster Controller", func() { Eventually(func() int { var badPodCount int clusterPods, _ = kubernetes.ListPods(ctx, k8sClient, updatedHumioCluster.Namespace, controllers.NewHumioNodeManagerFromHumioCluster(&updatedHumioCluster).GetPodLabels()) + suite.UsingClusterBy(key.Name, fmt.Sprintf("Found of %d pods", len(clusterPods))) for _, pod := range clusterPods { humioIndex, _ := kubernetes.GetContainerIndexByName(pod, controllers.HumioContainerName) + suite.UsingClusterBy(key.Name, fmt.Sprintf("Pod %s uses image %s and is using revision %s", pod.Spec.NodeName, pod.Spec.Containers[humioIndex].Image, pod.Annotations[controllers.PodRevisionAnnotation])) if pod.Spec.Containers[humioIndex].Image == updatedImage && pod.Annotations[controllers.PodRevisionAnnotation] == "2" { badPodCount++ } diff --git a/controllers/suite/clusters/suite_test.go b/controllers/suite/clusters/suite_test.go index 135051d1..9daecf0e 100644 --- a/controllers/suite/clusters/suite_test.go +++ b/controllers/suite/clusters/suite_test.go @@ -358,8 +358,8 @@ func markPodsWithRevisionAsReady(ctx context.Context, hnp *controllers.HumioNode suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("Found %d pods", len(foundPodList))) podListWithRevision := []corev1.Pod{} for i := range foundPodList { - foundPodRevisionValue, _ := foundPodList[i].Annotations[controllers.PodRevisionAnnotation] - foundPodHash, _ := foundPodList[i].Annotations[controllers.PodHashAnnotation] + foundPodRevisionValue := foundPodList[i].Annotations[controllers.PodRevisionAnnotation] + foundPodHash := foundPodList[i].Annotations[controllers.PodHashAnnotation] suite.UsingClusterBy(hnp.GetClusterName(), fmt.Sprintf("Pod=%s revision=%s podHash=%s podIP=%s", foundPodList[i].Name, foundPodRevisionValue, foundPodHash, foundPodList[i].Status.PodIP)) foundPodRevisionValueInt, _ := strconv.Atoi(foundPodRevisionValue) if foundPodRevisionValueInt == podRevision { diff --git a/controllers/suite/common.go b/controllers/suite/common.go index b2e6cfa7..8f88b02f 100644 --- a/controllers/suite/common.go +++ b/controllers/suite/common.go @@ -81,7 +81,7 @@ func MarkPodAsRunning(ctx context.Context, k8sClient client.Client, pod corev1.P } UsingClusterBy(clusterName, fmt.Sprintf("Simulating Humio container starts up and is marked Ready (pod phase %s)", pod.Status.Phase)) - pod.Status.PodIP = fmt.Sprintf("192.168.0.1") + pod.Status.PodIP = "192.168.0.1" pod.Status.Conditions = []corev1.PodCondition{ { Type: corev1.PodReady, From 35fcc6f58472d98192a87c130df78ab221ece293 Mon Sep 17 00:00:00 2001 From: Mike Rostermund Date: Fri, 16 Aug 2024 13:19:54 +0200 Subject: [PATCH 7/7] fix function name for validating searchdomain in mock for aggregate alerts --- pkg/humio/client.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/humio/client.go b/pkg/humio/client.go index 4d5ece1b..77a81013 100644 --- a/pkg/humio/client.go +++ b/pkg/humio/client.go @@ -813,7 +813,7 @@ func (h *ClientConfig) ValidateActionsForScheduledSearch(config *humioapi.Config } func (h *ClientConfig) AddAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - err := h.validateView(config, req, haa.Spec.ViewName) + err := h.validateSearchDomain(config, req, haa.Spec.ViewName) if err != nil { return &humioapi.AggregateAlert{}, fmt.Errorf("problem getting view for action: %w", err) } @@ -830,7 +830,7 @@ func (h *ClientConfig) AddAggregateAlert(config *humioapi.Config, req reconcile. } func (h *ClientConfig) GetAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - err := h.validateView(config, req, haa.Spec.ViewName) + err := h.validateSearchDomain(config, req, haa.Spec.ViewName) if err != nil { return &humioapi.AggregateAlert{}, fmt.Errorf("problem getting view for action %s: %w", haa.Spec.Name, err) } @@ -861,7 +861,7 @@ func (h *ClientConfig) GetAggregateAlert(config *humioapi.Config, req reconcile. } func (h *ClientConfig) UpdateAggregateAlert(config *humioapi.Config, req reconcile.Request, haa *humiov1alpha1.HumioAggregateAlert) (*humioapi.AggregateAlert, error) { - err := h.validateView(config, req, haa.Spec.ViewName) + err := h.validateSearchDomain(config, req, haa.Spec.ViewName) if err != nil { return &humioapi.AggregateAlert{}, fmt.Errorf("problem getting view for action %s: %w", haa.Spec.Name, err) }