feat(backend): allow stripping annotations

This allows same filtering we already have with labels. Fixes #312
This commit is contained in:
Łukasz Mierzwa
2019-01-15 22:12:23 +00:00
parent 9af5e7eeb4
commit e1f9686e3f
7 changed files with 119 additions and 2 deletions

View File

@@ -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:

View File

@@ -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()

View File

@@ -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")

View File

@@ -70,6 +70,8 @@ annotations:
hidden: []
visible:
- summary
keep: []
strip: []
custom:
css: /custom.css
js: /custom.js

View File

@@ -30,6 +30,8 @@ type configSchema struct {
}
Hidden []string
Visible []string
Keep []string
Strip []string
}
Custom struct {
CSS string

View File

@@ -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
}

View File

@@ -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)
}
}
}