From 8c2c0b2384172ee96212f1c0a1651bf0720267ab Mon Sep 17 00:00:00 2001 From: Mike Rostermund Date: Wed, 14 Aug 2024 14:18:57 +0200 Subject: [PATCH] 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 35a7bc176..ba82eaac4 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 a06ad15c0..e1467e0d6 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 12a89666f..7453b7eea 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 @@ -258,12 +259,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 557ed67a5..b833a0824 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 f97a105cc..78948ccb7 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 93bea4468..4c71792ad 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 87ac4575f..886daf2f7 100644 --- a/pkg/humio/client.go +++ b/pkg/humio/client.go @@ -52,10 +52,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 { @@ -204,7 +204,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() @@ -212,22 +212,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 @@ -328,24 +319,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 { @@ -354,7 +338,7 @@ func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.R hr.Spec.Description, ) if err != nil { - return &humioapi.Repository{}, err + return nil, err } } @@ -365,7 +349,7 @@ func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.R hr.Spec.AllowDataDeletion, ) if err != nil { - return &humioapi.Repository{}, err + return nil, err } } @@ -376,7 +360,7 @@ func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.R hr.Spec.AllowDataDeletion, ) if err != nil { - return &humioapi.Repository{}, err + return nil, err } } @@ -387,7 +371,7 @@ func (h *ClientConfig) UpdateRepository(config *humioapi.Config, req reconcile.R hr.Spec.AllowDataDeletion, ) if err != nil { - return &humioapi.Repository{}, err + return nil, err } } @@ -397,7 +381,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 } } @@ -418,18 +402,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) { @@ -449,7 +422,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 { @@ -458,7 +431,7 @@ func (h *ClientConfig) UpdateView(config *humioapi.Config, req reconcile.Request hv.Spec.Description, ) if err != nil { - return &humioapi.View{}, err + return nil, err } } @@ -468,7 +441,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 } } @@ -482,7 +455,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) @@ -496,46 +469,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) } @@ -553,7 +502,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) } @@ -600,25 +549,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 action %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) } @@ -637,7 +577,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) } @@ -666,7 +606,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 action %s: %w", hfa.Spec.Name, err) } @@ -697,7 +637,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) } @@ -714,7 +654,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) } @@ -744,7 +684,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) } @@ -761,7 +701,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) } @@ -792,7 +732,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) } @@ -829,17 +769,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 39e3e861c..3b965cc1e 100644 --- a/pkg/humio/client_mock.go +++ b/pkg/humio/client_mock.go @@ -67,7 +67,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), @@ -84,8 +84,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 @@ -108,8 +108,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, } @@ -182,8 +187,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, } @@ -254,8 +264,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, } @@ -324,6 +339,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, @@ -352,8 +369,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, } @@ -414,6 +436,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, @@ -476,8 +500,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, } @@ -556,8 +585,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, } @@ -647,8 +681,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, } @@ -715,8 +754,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, } @@ -800,11 +844,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) @@ -814,3 +859,22 @@ func (h *MockClientConfig) ClearHumioClientConnections() { h.apiClient.FilterAlert = make(map[resourceKey]humioapi.FilterAlert) 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 d8d3d177e..599af1f69 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 }