mirror of
https://github.com/prymitive/karma
synced 2026-05-05 03:16:51 +00:00
feat(backend): allow stripping annotations
This allows same filtering we already have with labels. Fixes #312
This commit is contained in:
@@ -140,12 +140,21 @@ annotations:
|
||||
hidden: bool
|
||||
hidden: list of strings
|
||||
visible: list of strings
|
||||
keep: list of strings
|
||||
strip: list of strings
|
||||
```
|
||||
|
||||
- `default:hidden` - bool, true if all annotations should be hidden by default.
|
||||
- `hidden` - list of annotations that should be hidden by default.
|
||||
- `visible` - list of annotations that should be visible by default when
|
||||
`default:hidden` is set to `true`.
|
||||
- `keep` - list of allowed annotations, if empty all annotations are allowed.
|
||||
- `strip` - list of ignored annotations.
|
||||
|
||||
The difference between `hidden`/`visible` and `keep`/`strip` is that hidden
|
||||
annotations are still accessible, but they are shown in the UI collapsed by
|
||||
default (only name is visible, value is shown after clicking), while stripped
|
||||
annotations are removed entirely and never presented to the user.
|
||||
|
||||
Example where all annotations except `summary` are hidden by default. If there
|
||||
are additional annotation keys user will need to click on the `+` icon to see
|
||||
@@ -158,11 +167,16 @@ annotations:
|
||||
hidden: []
|
||||
visible:
|
||||
- summary
|
||||
keep: []
|
||||
strip:
|
||||
- help
|
||||
- verylong
|
||||
```
|
||||
|
||||
Example where all annotations except `details` are visible by default. If
|
||||
`details` annotation is present on any alert user will need to click on the `+`
|
||||
icon to see it.
|
||||
icon to see it. Additionally `secret` annotation is stripped and never shown
|
||||
in the UI.
|
||||
|
||||
```yaml
|
||||
annotations:
|
||||
@@ -171,6 +185,9 @@ annotations:
|
||||
hidden:
|
||||
- details
|
||||
visible: []
|
||||
keep: []
|
||||
strip:
|
||||
- secret
|
||||
```
|
||||
|
||||
Defaults:
|
||||
|
||||
@@ -70,8 +70,9 @@ func DedupAlerts() []models.AlertGroup {
|
||||
ag := models.AlertGroup(agList[0])
|
||||
ag.Alerts = models.AlertList{}
|
||||
for _, alert := range alerts {
|
||||
// strip labels user doesn't want to see in the UI
|
||||
// strip labels and annotations user doesn't want to see in the UI
|
||||
alert.Labels = transform.StripLables(config.Config.Labels.Keep, config.Config.Labels.Strip, alert.Labels)
|
||||
alert.Annotations = transform.StripAnnotations(config.Config.Annotations.Keep, config.Config.Annotations.Strip, alert.Annotations)
|
||||
// calculate final alert state based on the most important value found
|
||||
// in the list of states from all instances
|
||||
alertLFP := alert.LabelsFingerprint()
|
||||
|
||||
@@ -39,6 +39,9 @@ func init() {
|
||||
"List of annotations that are hidden by default")
|
||||
pflag.StringSlice("annotations.visible", []string{},
|
||||
"List of annotations that are visible by default")
|
||||
pflag.StringSlice("annotations.keep", []string{},
|
||||
"List of annotations to keep, all other annotations will be stripped")
|
||||
pflag.StringSlice("annotations.strip", []string{}, "List of annotations to ignore")
|
||||
|
||||
pflag.String("config.file", "", "Full path to the configuration file")
|
||||
|
||||
@@ -128,6 +131,8 @@ func (config *configSchema) Read() {
|
||||
config.Annotations.Default.Hidden = v.GetBool("annotations.default.hidden")
|
||||
config.Annotations.Hidden = v.GetStringSlice("annotations.hidden")
|
||||
config.Annotations.Visible = v.GetStringSlice("annotations.visible")
|
||||
config.Annotations.Keep = v.GetStringSlice("annotations.keep")
|
||||
config.Annotations.Strip = v.GetStringSlice("annotations.strip")
|
||||
config.Custom.CSS = v.GetString("custom.css")
|
||||
config.Custom.JS = v.GetString("custom.js")
|
||||
config.Debug = v.GetBool("debug")
|
||||
|
||||
@@ -70,6 +70,8 @@ annotations:
|
||||
hidden: []
|
||||
visible:
|
||||
- summary
|
||||
keep: []
|
||||
strip: []
|
||||
custom:
|
||||
css: /custom.css
|
||||
js: /custom.js
|
||||
|
||||
@@ -30,6 +30,8 @@ type configSchema struct {
|
||||
}
|
||||
Hidden []string
|
||||
Visible []string
|
||||
Keep []string
|
||||
Strip []string
|
||||
}
|
||||
Custom struct {
|
||||
CSS string
|
||||
|
||||
@@ -3,6 +3,7 @@ package transform
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/slices"
|
||||
)
|
||||
|
||||
@@ -41,3 +42,22 @@ func StripReceivers(keptReceivers, ignoredReceivers []string, alertReceiver stri
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// StripAnnotations allows to ignore some annotations when pulling data
|
||||
// Alertmanager, it will return true if passed annotation name should be
|
||||
// stripped
|
||||
func StripAnnotations(keptAnnotations, ignoredAnnotations []string, sourceAnnotations models.Annotations) models.Annotations {
|
||||
// empty keep list means keep everything by default
|
||||
keepAll := len(keptAnnotations) == 0
|
||||
annotations := models.Annotations{}
|
||||
for _, annotation := range sourceAnnotations {
|
||||
// is explicitly marked to be kept
|
||||
inKeep := slices.StringInSlice(keptAnnotations, annotation.Name)
|
||||
// is explicitly marked to be stripped
|
||||
inStrip := slices.StringInSlice(ignoredAnnotations, annotation.Name)
|
||||
if (keepAll || inKeep) && !inStrip {
|
||||
annotations = append(annotations, annotation)
|
||||
}
|
||||
}
|
||||
return annotations
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/prymitive/karma/internal/models"
|
||||
"github.com/prymitive/karma/internal/transform"
|
||||
)
|
||||
|
||||
@@ -162,3 +163,72 @@ func TestStripReceivers(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type stripAnnotationTest struct {
|
||||
strip []string
|
||||
keep []string
|
||||
before models.Annotations
|
||||
after models.Annotations
|
||||
}
|
||||
|
||||
var stripAnnotationTests = []stripAnnotationTest{
|
||||
{
|
||||
strip: []string{},
|
||||
keep: []string{},
|
||||
before: models.Annotations{
|
||||
models.Annotation{Name: "foo", Value: "bar"},
|
||||
},
|
||||
after: models.Annotations{
|
||||
models.Annotation{Name: "foo", Value: "bar"},
|
||||
},
|
||||
},
|
||||
{
|
||||
strip: []string{"foo"},
|
||||
keep: []string{},
|
||||
before: models.Annotations{
|
||||
models.Annotation{Name: "foo", Value: "bar"},
|
||||
},
|
||||
after: models.Annotations{},
|
||||
},
|
||||
{
|
||||
strip: []string{"foo"},
|
||||
keep: []string{},
|
||||
before: models.Annotations{
|
||||
models.Annotation{Name: "foo", Value: "bar"},
|
||||
models.Annotation{Name: "boo", Value: "baz"},
|
||||
},
|
||||
after: models.Annotations{
|
||||
models.Annotation{Name: "boo", Value: "baz"},
|
||||
},
|
||||
},
|
||||
{
|
||||
strip: []string{},
|
||||
keep: []string{"foo"},
|
||||
before: models.Annotations{
|
||||
models.Annotation{Name: "foo", Value: "bar"},
|
||||
},
|
||||
after: models.Annotations{
|
||||
models.Annotation{Name: "foo", Value: "bar"},
|
||||
},
|
||||
},
|
||||
{
|
||||
strip: []string{},
|
||||
keep: []string{"foo"},
|
||||
before: models.Annotations{
|
||||
models.Annotation{Name: "foo", Value: "bar"},
|
||||
models.Annotation{Name: "boo", Value: "baz"},
|
||||
},
|
||||
after: models.Annotations{
|
||||
models.Annotation{Name: "foo", Value: "bar"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestStripAnnotations(t *testing.T) {
|
||||
for _, testCase := range stripAnnotationTests {
|
||||
annotations := transform.StripAnnotations(testCase.keep, testCase.strip, testCase.before)
|
||||
if !reflect.DeepEqual(annotations, testCase.after) {
|
||||
t.Errorf("StripAnnotations failed, expected %v, got %v", testCase.after, annotations)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user