diff --git a/cmd/karma/acl.go b/cmd/karma/acl.go index 87d3c40e4..5ed7faa4b 100644 --- a/cmd/karma/acl.go +++ b/cmd/karma/acl.go @@ -4,12 +4,12 @@ import ( "errors" "fmt" "regexp" + "slices" "github.com/prymitive/karma/internal/alertmanager" "github.com/prymitive/karma/internal/config" "github.com/prymitive/karma/internal/models" "github.com/prymitive/karma/internal/regex" - "github.com/prymitive/karma/internal/slices" ) const ( @@ -114,7 +114,7 @@ type silenceACL struct { func (acl *silenceACL) isAllowed(amName string, silence *models.Silence, groups []string) (bool, error) { groupMatch := len(acl.Scope.Groups) == 0 for _, aclGroup := range acl.Scope.Groups { - if slices.StringInSlice(groups, aclGroup) { + if slices.Contains(groups, aclGroup) { groupMatch = true break } @@ -172,7 +172,7 @@ func newSilenceACLFromConfig(cfg config.SilenceACLRule) (*silenceACL, error) { Matchers: aclMatchers{}, } - if !slices.StringInSlice(allACLActions, acl.Action) { + if !slices.Contains(allACLActions, acl.Action) { return nil, fmt.Errorf("silence ACL rule requires 'action' to be one of %v, got %q", allACLActions, acl.Action) } diff --git a/cmd/karma/alert_history.go b/cmd/karma/alert_history.go index ae48b01bb..5a5dd393c 100644 --- a/cmd/karma/alert_history.go +++ b/cmd/karma/alert_history.go @@ -9,6 +9,7 @@ import ( "io" "net/http" "net/url" + "slices" "sort" "strings" "sync" @@ -24,7 +25,6 @@ import ( "github.com/prymitive/karma/internal/alertmanager" "github.com/prymitive/karma/internal/config" "github.com/prymitive/karma/internal/mapper" - "github.com/prymitive/karma/internal/slices" uriUtil "github.com/prymitive/karma/internal/uri" ) @@ -338,7 +338,7 @@ func countAlerts(uri string, timeout time.Duration, transport http.RoundTripper, lv := model.LabelSet{} for k, v := range labels { - if slices.StringInSlice(names, k) { + if slices.Contains(names, k) { lv[model.LabelName(k)] = model.LabelValue(v) } } diff --git a/cmd/karma/alerts.go b/cmd/karma/alerts.go index 24c7a1cfd..ebbcf9019 100644 --- a/cmd/karma/alerts.go +++ b/cmd/karma/alerts.go @@ -3,6 +3,7 @@ package main import ( "fmt" "math" + "slices" "sort" "github.com/fvbommel/sortorder" @@ -12,7 +13,6 @@ import ( "github.com/prymitive/karma/internal/config" "github.com/prymitive/karma/internal/filters" "github.com/prymitive/karma/internal/models" - "github.com/prymitive/karma/internal/slices" "github.com/prymitive/karma/internal/uri" ) @@ -299,7 +299,7 @@ func autoGridLabel(dedupedAlerts []models.AlertGroup) string { candidates := map[string]int{} for key, vals := range labelToAlertCount { - if slices.StringInSlice(config.Config.Grid.Auto.Ignore, key) { + if slices.Contains(config.Config.Grid.Auto.Ignore, key) { continue } var total int diff --git a/cmd/karma/auth.go b/cmd/karma/auth.go index 721f1c960..0d5dac2d6 100644 --- a/cmd/karma/auth.go +++ b/cmd/karma/auth.go @@ -3,11 +3,11 @@ package main import ( "context" "net/http" + "slices" "strings" "github.com/prymitive/karma/internal/config" "github.com/prymitive/karma/internal/regex" - "github.com/prymitive/karma/internal/slices" ) type authUserKey string @@ -15,7 +15,7 @@ type authUserKey string func userGroups(username string) []string { groups := []string{} for _, authGroup := range config.Config.Authorization.Groups { - if slices.StringInSlice(authGroup.Members, username) { + if slices.Contains(authGroup.Members, username) { groups = append(groups, authGroup.Name) } } @@ -39,7 +39,7 @@ func groupsFromHeaders(r *http.Request, groupName, groupValueRegex, groupValueSe func headerAuth(name, valueRegex, groupName, groupValueRegex, groupValueSeparator string, allowBypass []string) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if slices.StringInSlice(allowBypass, r.URL.Path) { + if slices.Contains(allowBypass, r.URL.Path) { next.ServeHTTP(w, r) return } @@ -92,7 +92,7 @@ func getGroupsFromContext(r *http.Request) []string { func basicAuth(creds map[string]string, groupName, groupValueRegex, groupValueSeparator string, allowBypass []string) func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if slices.StringInSlice(allowBypass, r.URL.Path) { + if slices.Contains(allowBypass, r.URL.Path) { next.ServeHTTP(w, r) return } diff --git a/cmd/karma/views.go b/cmd/karma/views.go index 074e3ade5..f9f112574 100644 --- a/cmd/karma/views.go +++ b/cmd/karma/views.go @@ -9,6 +9,7 @@ import ( "io" "net/http" "runtime" + "slices" "sort" "strings" "time" @@ -21,7 +22,7 @@ import ( "github.com/prymitive/karma/internal/config" "github.com/prymitive/karma/internal/filters" "github.com/prymitive/karma/internal/models" - "github.com/prymitive/karma/internal/slices" + sliceutils "github.com/prymitive/karma/internal/slices" "github.com/prymitive/karma/internal/transform" "github.com/rs/zerolog/log" @@ -536,10 +537,10 @@ func labelsSettings(grids []models.APIGrid, store models.LabelsSettings) { func labelSettings(name string, store models.LabelsSettings) { var isStatic, isValueOnly bool - if slices.StringInSlice(config.Config.Labels.Color.Static, name) { + if slices.Contains(config.Config.Labels.Color.Static, name) { isStatic = true } - if slices.StringInSlice(config.Config.Labels.ValueOnly, name) || slices.MatchesAnyRegex(name, config.Config.Labels.CompiledValueOnlyRegex) { + if slices.Contains(config.Config.Labels.ValueOnly, name) || sliceutils.MatchesAnyRegex(name, config.Config.Labels.CompiledValueOnlyRegex) { isValueOnly = true } if isStatic || isValueOnly { @@ -577,12 +578,12 @@ func autocomplete(w http.ResponseWriter, r *http.Request) { dedupedAutocomplete := alertmanager.DedupAutocomplete() for _, hint := range dedupedAutocomplete { - if strings.HasPrefix(strings.ToLower(hint.Value), strings.ToLower(term)) { - acData = append(acData, hint.Value) + if strings.HasPrefix(strings.ToLower(hint.Value.Value()), strings.ToLower(term)) { + acData = append(acData, hint.Value.Value()) } else { for _, token := range hint.Tokens { - if strings.HasPrefix(strings.ToLower(token), strings.ToLower(term)) { - acData = append(acData, hint.Value) + if strings.HasPrefix(strings.ToLower(token.Value()), strings.ToLower(term)) { + acData = append(acData, hint.Value.Value()) } } } @@ -630,7 +631,7 @@ func silences(w http.ResponseWriter, r *http.Request) { upstreams := getUpstreams() for _, u := range upstreams.Instances { if strings.ToLower(u.Name) == searchTerm || strings.ToLower(u.Cluster) == searchTerm { - if !slices.StringInSlice(clusters, u.Cluster) { + if !slices.Contains(clusters, u.Cluster) { clusters = append(clusters, strings.ToLower(u.Cluster)) } } @@ -648,7 +649,7 @@ func silences(w http.ResponseWriter, r *http.Request) { isMatch = true case "@cluster="+strings.ToLower(silence.Cluster) == searchTerm: isMatch = true - case slices.StringInSlice(clusters, strings.ToLower(silence.Cluster)): + case slices.Contains(clusters, strings.ToLower(silence.Cluster)): isMatch = true case strings.Contains(strings.ToLower(silence.Silence.Comment), searchTerm): isMatch = true diff --git a/cmd/karma/views_test.go b/cmd/karma/views_test.go index f701d37c5..6d278abc0 100644 --- a/cmd/karma/views_test.go +++ b/cmd/karma/views_test.go @@ -11,6 +11,7 @@ import ( "net/http/httptest" "os" "regexp" + "slices" "sort" "strconv" "strings" @@ -25,7 +26,6 @@ import ( "github.com/prymitive/karma/internal/mock" "github.com/prymitive/karma/internal/models" "github.com/prymitive/karma/internal/regex" - "github.com/prymitive/karma/internal/slices" "github.com/go-chi/chi/v5" "github.com/google/go-cmp/cmp" @@ -634,7 +634,7 @@ func TestValidateAllAlerts(t *testing.T) { } for _, ag := range ur.Grids[0].AlertGroups { for _, a := range ag.Alerts { - if !slices.StringInSlice(models.AlertStateList, a.State) { + if !slices.Contains(models.AlertStateList, a.State) { t.Errorf("Invalid alert status '%s', not in %v", a.State, models.AlertStateList) } if len(a.Alertmanager) == 0 { diff --git a/internal/alertmanager/dedup.go b/internal/alertmanager/dedup.go index 87d003cd5..9fb4ccae6 100644 --- a/internal/alertmanager/dedup.go +++ b/internal/alertmanager/dedup.go @@ -1,12 +1,13 @@ package alertmanager import ( + "slices" "sort" "time" + "unique" "github.com/prymitive/karma/internal/config" "github.com/prymitive/karma/internal/models" - "github.com/prymitive/karma/internal/slices" "github.com/prymitive/karma/internal/transform" "github.com/rs/zerolog/log" @@ -104,9 +105,9 @@ func DedupAlerts() []models.AlertGroup { // in the list of states from all instances alertLFP := alert.LabelsFingerprint() switch { - case slices.StringInSlice(alertStates[alertLFP], models.AlertStateActive): + case slices.Contains(alertStates[alertLFP], models.AlertStateActive): alert.State = models.AlertStateActive - case slices.StringInSlice(alertStates[alertLFP], models.AlertStateSuppressed): + case slices.Contains(alertStates[alertLFP], models.AlertStateSuppressed): alert.State = models.AlertStateSuppressed default: alert.State = models.AlertStateUnprocessed @@ -187,7 +188,7 @@ func DedupColors() models.LabelsColorMap { // DedupAutocomplete returns a list of autocomplete hints merged from all // Alertmanager upstreams func DedupAutocomplete() []models.Autocomplete { - uniqueAutocomplete := map[string]*models.Autocomplete{} + uniqueAutocomplete := map[unique.Handle[string]]*models.Autocomplete{} upstreams := GetAlertmanagers() @@ -197,7 +198,7 @@ func DedupAutocomplete() []models.Autocomplete { h, found := uniqueAutocomplete[hint.Value] if found { for _, token := range hint.Tokens { - if !slices.StringInSlice(h.Tokens, token) { + if !slices.Contains(h.Tokens, token) { h.Tokens = append(h.Tokens, token) } } diff --git a/internal/alertmanager/models.go b/internal/alertmanager/models.go index 3c93c2ccd..cc659cb1f 100644 --- a/internal/alertmanager/models.go +++ b/internal/alertmanager/models.go @@ -7,6 +7,7 @@ import ( "sort" "sync" "time" + "unique" "github.com/prymitive/karma/internal/config" "github.com/prymitive/karma/internal/filters" @@ -239,7 +240,7 @@ func (am *Alertmanager) pullAlerts(version string, si *intern.Interner) error { dedupedGroups := make([]models.AlertGroup, 0, len(uniqueGroups)) colors := models.LabelsColorMap{} - autocompleteMap := map[string]*models.Autocomplete{} + autocompleteMap := map[unique.Handle[string]]*models.Autocomplete{} log.Info(). Str("alertmanager", am.Name). diff --git a/internal/config/config.go b/internal/config/config.go index e0da49f91..a31c55225 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -7,11 +7,11 @@ import ( "fmt" "os" "regexp" + "slices" "strings" "time" "github.com/prymitive/karma/internal/regex" - "github.com/prymitive/karma/internal/slices" "github.com/prymitive/karma/internal/uri" "github.com/knadh/koanf" @@ -352,7 +352,7 @@ func (config *configSchema) Read(flags *pflag.FlagSet) (string, error) { config.Authentication.Enabled = true } - if !slices.StringInSlice([]string{"omit", "include", "same-origin"}, config.Alertmanager.CORS.Credentials) { + if !slices.Contains([]string{"omit", "include", "same-origin"}, config.Alertmanager.CORS.Credentials) { return "", fmt.Errorf("invalid alertmanager.cors.credentials value '%s', allowed options: omit, inclue, same-origin", config.Alertmanager.CORS.Credentials) } @@ -366,7 +366,7 @@ func (config *configSchema) Read(flags *pflag.FlagSet) (string, error) { if s.CORS.Credentials == "" { config.Alertmanager.Servers[i].CORS.Credentials = config.Alertmanager.CORS.Credentials } - if !slices.StringInSlice([]string{"omit", "include", "same-origin"}, config.Alertmanager.Servers[i].CORS.Credentials) { + if !slices.Contains([]string{"omit", "include", "same-origin"}, config.Alertmanager.Servers[i].CORS.Credentials) { return "", fmt.Errorf("invalid cors.credentials value '%s' for alertmanager '%s', allowed options: omit, inclue, same-origin", config.Alertmanager.Servers[i].CORS.Credentials, s.Name) } } @@ -434,15 +434,15 @@ func (config *configSchema) Read(flags *pflag.FlagSet) (string, error) { } } - if !slices.StringInSlice([]string{"disabled", "startsAt", "label"}, config.Grid.Sorting.Order) { + if !slices.Contains([]string{"disabled", "startsAt", "label"}, config.Grid.Sorting.Order) { return "", fmt.Errorf("invalid grid.sorting.order value '%s', allowed options: disabled, startsAt, label", config.Grid.Sorting.Order) } - if !slices.StringInSlice([]string{"expanded", "collapsed", "collapsedOnMobile"}, config.UI.CollapseGroups) { + if !slices.Contains([]string{"expanded", "collapsed", "collapsedOnMobile"}, config.UI.CollapseGroups) { return "", fmt.Errorf("invalid ui.collapseGroups value '%s', allowed options: expanded, collapsed, collapsedOnMobile", config.UI.CollapseGroups) } - if !slices.StringInSlice([]string{"light", "dark", "auto"}, config.UI.Theme) { + if !slices.Contains([]string{"light", "dark", "auto"}, config.UI.Theme) { return "", fmt.Errorf("invalid ui.theme value '%s', allowed options: light, dark, auto", config.UI.Theme) } diff --git a/internal/filters/autocomplete.go b/internal/filters/autocomplete.go index f41c8d9f4..2cdc75d58 100644 --- a/internal/filters/autocomplete.go +++ b/internal/filters/autocomplete.go @@ -1,17 +1,24 @@ package filters import ( + "unique" + "github.com/prymitive/karma/internal/models" ) type autocompleteFactory func(name string, operators []string, alerts []models.Alert) []models.Autocomplete func makeAC(value string, tokens []string) models.Autocomplete { - acHint := models.Autocomplete{ - Value: value, - Tokens: tokens, + uTokens := make([]unique.Handle[string], 0, len(tokens)) + for _, token := range tokens { + uTokens = append(uTokens, unique.Make(token)) } - acHint.Tokens = append(acHint.Tokens, value) + + acHint := models.Autocomplete{ + Value: unique.Make(value), + Tokens: uTokens, + } + acHint.Tokens = append(acHint.Tokens, unique.Make(value)) return acHint } diff --git a/internal/filters/autocomplete_test.go b/internal/filters/autocomplete_test.go index 0842c79b3..19ba16d4e 100644 --- a/internal/filters/autocomplete_test.go +++ b/internal/filters/autocomplete_test.go @@ -134,7 +134,7 @@ func TestBuildAutocomplete(t *testing.T) { for _, acTest := range acTests { result := []string{} for _, hint := range filters.BuildAutocomplete(acTest.Alerts) { - result = append(result, hint.Value) + result = append(result, hint.Value.Value()) } sort.Strings(result) diff --git a/internal/filters/filter.go b/internal/filters/filter.go index feacf059c..c03b3b867 100644 --- a/internal/filters/filter.go +++ b/internal/filters/filter.go @@ -3,10 +3,10 @@ package filters import ( "fmt" "regexp" + "slices" "strings" "github.com/prymitive/karma/internal/models" - "github.com/prymitive/karma/internal/slices" ) // FilterT provides methods for interacting with alert filters @@ -124,7 +124,7 @@ func NewFilter(expression string) FilterT { // filter name doesn't match, keep searching continue } - if !slices.StringInSlice(fc.SupportedOperators, operator) { + if !slices.Contains(fc.SupportedOperators, operator) { return &invalid } // we validate operator above, no need to re-check diff --git a/internal/filters/filter_state.go b/internal/filters/filter_state.go index 7c0f77779..1f8b4a397 100644 --- a/internal/filters/filter_state.go +++ b/internal/filters/filter_state.go @@ -2,10 +2,10 @@ package filters import ( "fmt" + "slices" "strings" "github.com/prymitive/karma/internal/models" - "github.com/prymitive/karma/internal/slices" ) type stateFilter struct { @@ -20,7 +20,7 @@ func (filter *stateFilter) init(name string, matcher *matcherT, rawText string, filter.RawText = rawText filter.IsValid = isValid filter.Value = value - if !slices.StringInSlice(models.AlertStateList, value) { + if !slices.Contains(models.AlertStateList, value) { filter.IsValid = false } } diff --git a/internal/filters/filter_test.go b/internal/filters/filter_test.go index 4b01d93a9..592f66596 100644 --- a/internal/filters/filter_test.go +++ b/internal/filters/filter_test.go @@ -2,6 +2,7 @@ package filters_test import ( "encoding/json" + "slices" "strings" "testing" "time" @@ -9,7 +10,6 @@ import ( "github.com/prymitive/karma/internal/alertmanager" "github.com/prymitive/karma/internal/filters" "github.com/prymitive/karma/internal/models" - "github.com/prymitive/karma/internal/slices" "github.com/rs/zerolog" ) @@ -903,7 +903,7 @@ func TestFilters(t *testing.T) { t.Errorf("[%s] GetIsValid() returned %#v while %#v was expected", ft.Expression, f.GetIsValid(), ft.IsValid) } if f.GetIsValid() { - isAlertmanagerFilter := slices.StringInSlice( + isAlertmanagerFilter := slices.Contains( []string{"@age", "@alertmanager", "@cluster", "@inhibited", "@inhibited_by", "@state", "@silenced_by", "@silence_ticket", "@silence_author", "@fingerprint"}, f.GetName()) if isAlertmanagerFilter != f.GetIsAlertmanagerFilter() { diff --git a/internal/models/annotation.go b/internal/models/annotation.go index 0a43c097b..aba9a8d58 100644 --- a/internal/models/annotation.go +++ b/internal/models/annotation.go @@ -2,13 +2,13 @@ package models import ( "net/url" + "slices" "sort" "strings" "github.com/fvbommel/sortorder" "github.com/prymitive/karma/internal/config" - "github.com/prymitive/karma/internal/slices" ) // Annotation extends Alertmanager scheme of key:value with additional data @@ -90,7 +90,7 @@ func isLink(s string) bool { if err != nil { return false } - if slices.StringInSlice(linkSchemes, u.Scheme) { + if slices.Contains(linkSchemes, u.Scheme) { // parses with url.Parse and scheme is in the list of supported schemes return true } @@ -98,11 +98,11 @@ func isLink(s string) bool { } func isVisible(name string) bool { - if slices.StringInSlice(config.Config.Annotations.Visible, name) { + if slices.Contains(config.Config.Annotations.Visible, name) { // annotation was explicitly marked as visible return true } - if slices.StringInSlice(config.Config.Annotations.Hidden, name) { + if slices.Contains(config.Config.Annotations.Hidden, name) { // annotation was explicitly marked as hidden return false } @@ -115,5 +115,5 @@ func isVisible(name string) bool { } func isAction(name string) bool { - return slices.StringInSlice(config.Config.Annotations.Actions, name) + return slices.Contains(config.Config.Annotations.Actions, name) } diff --git a/internal/models/api.go b/internal/models/api.go index 66bc233ed..c8729d524 100644 --- a/internal/models/api.go +++ b/internal/models/api.go @@ -3,12 +3,12 @@ package models import ( "fmt" "net/url" + "slices" "sort" "strings" + "unique" "github.com/fvbommel/sortorder" - - "github.com/prymitive/karma/internal/slices" ) // Filter holds returned data on any filter passed by the user as part of the query @@ -153,7 +153,7 @@ func (ag *APIAlertGroup) dedupLabels() { func (ag *APIAlertGroup) removeGroupingLabels(dropNames []string) { newGroupLabels := Labels{} for _, l := range ag.Labels { - if slices.StringInSlice(dropNames, l.Name) { + if slices.Contains(dropNames, l.Name) { continue } newGroupLabels = newGroupLabels.Add(l) @@ -163,7 +163,7 @@ func (ag *APIAlertGroup) removeGroupingLabels(dropNames []string) { for i, alert := range ag.Alerts { newAlertLabels := Labels{} for _, l := range alert.Labels { - if slices.StringInSlice(dropNames, l.Name) { + if slices.Contains(dropNames, l.Name) { // skip all labels from the drop list continue } @@ -202,7 +202,7 @@ func (ag *APIAlertGroup) dedupAnnotations() { for _, annotation := range alert.Annotations { key := fmt.Sprintf("%s\n%s", annotation.Name, annotation.Value) if annotationCount[key] == totalAlerts { - if !slices.StringInSlice(sharedKeys, key) { + if !slices.Contains(sharedKeys, key) { sharedAnnotations = append(sharedAnnotations, annotation) sharedKeys = append(sharedKeys, key) } @@ -225,7 +225,7 @@ func (ag *APIAlertGroup) dedupSilences() { // process each cluster only once, rather than each alertmanager instance clusters := []string{} for _, am := range alert.Alertmanager { - if slices.StringInSlice(clusters, am.Cluster) { + if slices.Contains(clusters, am.Cluster) { continue } clusters = append(clusters, am.Cluster) @@ -349,7 +349,7 @@ func (ag *APIAlertGroup) populateAllLabels() { if _, ok := ag.AllLabels[alert.State][l.Name]; !ok { ag.AllLabels[alert.State][l.Name] = []string{} } - if !slices.StringInSlice(ag.AllLabels[alert.State][l.Name], l.Value) { + if !slices.Contains(ag.AllLabels[alert.State][l.Name], l.Value) { ag.AllLabels[alert.State][l.Name] = append(ag.AllLabels[alert.State][l.Name], l.Value) } } @@ -482,8 +482,8 @@ type AlertsResponse struct { // Autocomplete is the structure of autocomplete object for filter hints // this is internal representation, not what's returned to the user type Autocomplete struct { - Value string `json:"value"` - Tokens []string `json:"tokens"` + Value unique.Handle[string] `json:"value"` + Tokens []unique.Handle[string] `json:"tokens"` } type Counters struct { diff --git a/internal/slices/slices.go b/internal/slices/slices.go index 94ffbd981..7e7c95ec4 100644 --- a/internal/slices/slices.go +++ b/internal/slices/slices.go @@ -6,26 +6,6 @@ import ( "regexp" ) -// BoolInSlice returns true if given bool is found in a slice of bools -func BoolInSlice(boolArray []bool, value bool) bool { - for _, s := range boolArray { - if s == value { - return true - } - } - return false -} - -// StringInSlice returns true if given string is found in a slice of strings -func StringInSlice(stringArray []string, value string) bool { - for _, s := range stringArray { - if s == value { - return true - } - } - return false -} - // StringSliceToSHA1 returns a SHA1 hash computed from a slice of strings func StringSliceToSHA1(stringArray []string) (string, error) { h := sha1.New() diff --git a/internal/slices/slices_test.go b/internal/slices/slices_test.go index 9490b1e17..642823e2d 100644 --- a/internal/slices/slices_test.go +++ b/internal/slices/slices_test.go @@ -8,112 +8,6 @@ import ( "github.com/google/go-cmp/cmp" ) -type stringSliceTest struct { - value string - array []string - found bool -} - -var stringSliceTests = []stringSliceTest{ - { - array: []string{}, - value: "aa", - found: false, - }, - { - array: []string{"aa", "bb", "cc", "dd"}, - value: "aa", - found: true, - }, - { - array: []string{"aa", "bb", "cc", "dd"}, - value: "bb", - found: true, - }, - { - array: []string{"aa", "bb", "cc", "dd"}, - value: "cc", - found: true, - }, - { - array: []string{"aa", "bb", "cc", "dd"}, - value: "dd", - found: true, - }, - { - array: []string{"aa", "bb", "cc", "dd"}, - value: "bbcc", - found: false, - }, - { - array: []string{"aa", "bb", "cc", "dd"}, - value: "b", - found: false, - }, - { - array: []string{"aa", "bb", "cc", "dd"}, - value: "", - found: false, - }, -} - -func TestStringInSlice(t *testing.T) { - for _, testCase := range stringSliceTests { - found := slices.StringInSlice(testCase.array, testCase.value) - if found != testCase.found { - t.Errorf("Check if '%s' in slice %v returned %t, expected %t", testCase.value, testCase.array, found, testCase.found) - } - } -} - -type boolSliceTest struct { - array []bool - value bool - found bool -} - -var boolSliceTests = []boolSliceTest{ - { - array: []bool{}, - value: true, - found: false, - }, - { - array: []bool{}, - value: false, - found: false, - }, - { - array: []bool{true, false}, - value: true, - found: true, - }, - { - array: []bool{true, false}, - value: false, - found: true, - }, - { - array: []bool{false}, - value: true, - found: false, - }, - { - array: []bool{true}, - value: false, - found: false, - }, -} - -func TestBoolInSlice(t *testing.T) { - for _, testCase := range boolSliceTests { - found := slices.BoolInSlice(testCase.array, testCase.value) - if found != testCase.found { - t.Errorf("Check if '%t' in slice %v returned %t, expected %t", testCase.value, testCase.array, found, testCase.found) - } - } -} - func TestStringSliceToSHA1(t *testing.T) { s, err := slices.StringSliceToSHA1([]string{"a", "b", "c"}) if err != nil { diff --git a/internal/transform/colors.go b/internal/transform/colors.go index 226be78e4..5e82dc592 100644 --- a/internal/transform/colors.go +++ b/internal/transform/colors.go @@ -5,10 +5,10 @@ import ( "image/color" "io" "math/rand" + "slices" "github.com/prymitive/karma/internal/config" "github.com/prymitive/karma/internal/models" - "github.com/prymitive/karma/internal/slices" "github.com/prymitive/randomcolor" "github.com/rs/zerolog/log" @@ -84,7 +84,7 @@ func ColorLabel(colorStore models.LabelsColorMap, key, val string) { } // if no custom color is found then generate unique colors if needed - if slices.StringInSlice(config.Config.Labels.Color.Unique, key) { + if slices.Contains(config.Config.Labels.Color.Unique, key) { if _, found := colorStore[key]; !found { colorStore[key] = make(map[string]models.LabelColors) } diff --git a/internal/transform/strip.go b/internal/transform/strip.go index 97ab0504b..a282801bc 100644 --- a/internal/transform/strip.go +++ b/internal/transform/strip.go @@ -2,11 +2,12 @@ package transform import ( "regexp" + "slices" "sort" "strings" "github.com/prymitive/karma/internal/models" - "github.com/prymitive/karma/internal/slices" + sliceutils "github.com/prymitive/karma/internal/slices" ) // StripLables allows filtering out some labels from alerts @@ -25,9 +26,9 @@ func StripLables(keptLabels, ignoredLabels []string, keptLabelsRegex, ignoredLab var inKeep, inStrip bool for _, label := range sourceLabels { // is explicitly marked to be kept - inKeep = slices.StringInSlice(keptLabels, label.Name) || slices.MatchesAnyRegex(label.Name, keptLabelsRegex) + inKeep = slices.Contains(keptLabels, label.Name) || sliceutils.MatchesAnyRegex(label.Name, keptLabelsRegex) // is explicitly marked to be stripped - inStrip = slices.StringInSlice(ignoredLabels, label.Name) || slices.MatchesAnyRegex(label.Name, ignoredLabelsRegex) + inStrip = slices.Contains(ignoredLabels, label.Name) || sliceutils.MatchesAnyRegex(label.Name, ignoredLabelsRegex) if (keepAll || inKeep) && !inStrip { l := models.Label{ Name: label.Name, @@ -48,9 +49,9 @@ func StripReceivers(keptReceivers, ignoredReceivers []string, keptReceiversRegex // empty keep lists means keep everything by default keepAll := len(keptReceivers) == 0 && len(keptReceiversRegex) == 0 // is explicitly marked to be kept - inKeep := slices.StringInSlice(keptReceivers, alertReceiver) || slices.MatchesAnyRegex(alertReceiver, keptReceiversRegex) + inKeep := slices.Contains(keptReceivers, alertReceiver) || sliceutils.MatchesAnyRegex(alertReceiver, keptReceiversRegex) // is explicitly marked to be stripped - inStrip := slices.StringInSlice(ignoredReceivers, alertReceiver) || slices.MatchesAnyRegex(alertReceiver, ignoredReceiversRegex) + inStrip := slices.Contains(ignoredReceivers, alertReceiver) || sliceutils.MatchesAnyRegex(alertReceiver, ignoredReceiversRegex) if (keepAll || inKeep) && !inStrip { return false @@ -67,9 +68,9 @@ func StripAnnotations(keptAnnotations, ignoredAnnotations []string, sourceAnnota annotations := make(models.Annotations, 0, len(sourceAnnotations)) for _, annotation := range sourceAnnotations { // is explicitly marked to be kept - inKeep := slices.StringInSlice(keptAnnotations, annotation.Name) + inKeep := slices.Contains(keptAnnotations, annotation.Name) // is explicitly marked to be stripped - inStrip := slices.StringInSlice(ignoredAnnotations, annotation.Name) + inStrip := slices.Contains(ignoredAnnotations, annotation.Name) if (keepAll || inKeep) && !inStrip { annotations = append(annotations, annotation) }