begins work on routing lib
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"github.com/grafana/alerting-api/pkg/api"
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
)
|
||||
|
||||
// GrafanaAlertingConfig contains only the Grafana managed alerting configurations.
|
||||
type GrafanaAlertingConfig struct {
|
||||
Route *config.Route `yaml:"route,omitempty" json:"route,omitempty"`
|
||||
Templates []string `yaml:"templates" json:"templates"`
|
||||
Receivers []*GrafanaReceiver `yaml:"receivers,omitempty" json:"receivers,omitempty"`
|
||||
}
|
||||
|
||||
type GrafanaReceiver struct {
|
||||
// A unique identifier for this receiver.
|
||||
Name string `yaml:"name" json:"name"`
|
||||
api.GrafanaReceivers
|
||||
}
|
||||
|
||||
func SplitAlertingConfig(apiConf api.ApiAlertingConfig) (amConfig config.Config, gConfig GrafanaAlertingConfig, err error) {
|
||||
|
||||
var gReceivers []*GrafanaReceiver
|
||||
var amReceivers []*config.Receiver
|
||||
for _, r := range apiConf.Receivers {
|
||||
t := r.Type()
|
||||
if t == api.GrafanaReceiverType {
|
||||
gReceivers = append(gReceivers, &GrafanaReceiver{
|
||||
Name: r.Name,
|
||||
GrafanaReceivers: r.GrafanaReceivers,
|
||||
})
|
||||
} else {
|
||||
amReceivers = append(amReceivers, &r.Receiver)
|
||||
}
|
||||
}
|
||||
|
||||
// Create Grafana specific config
|
||||
gConfig.Templates = apiConf.Templates
|
||||
gConfig.Route = apiConf.GrafanaManagedRoute
|
||||
gConfig.Receivers = gReceivers
|
||||
|
||||
// Create AM specific config
|
||||
amConfig = apiConf.Config
|
||||
amConfig.Route = apiConf.AlertManagerRoute
|
||||
amConfig.Receivers = amReceivers
|
||||
|
||||
return amConfig, gConfig, nil
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/alerting-api/pkg/api"
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
)
|
||||
|
||||
// GrafanaAlertingConfig contains only the Grafana managed alerting configurations.
|
||||
type GrafanaAlertingConfig struct {
|
||||
api.GrafanaReceivers
|
||||
Route *config.Route `yaml:"route,omitempty" json:"route,omitempty"`
|
||||
Templates []string `yaml:"templates" json:"templates"`
|
||||
}
|
||||
|
||||
// func SplitAlertingConfig(apiConf api.ApiAlertingConfig) (amConfig config.Config, gConfig GrafanaAlertingConfig, err error) {
|
||||
|
||||
// }
|
||||
|
||||
// func MergeAlertingConfigs(amConfig config.Config, gConfig GrafanaAlertingConfig) (conf api.ApiAlertingConfig, err error) {
|
||||
// }
|
||||
|
||||
// Routing trees must either contain only Grafana Managed receiver types or AlertManager receiver types
|
||||
func SplitRoutes(routes []*config.Route, receivers map[string]api.ReceiverType) (gRoutes, amRoutes []*config.Route, err error) {
|
||||
for _, route := range routes {
|
||||
var grafanaCt, amCt int
|
||||
for _, receiver := range allReceivers(route) {
|
||||
t, ok := receivers[receiver]
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("unexpected receiver (%s) is undefined", receiver)
|
||||
}
|
||||
|
||||
if t == api.GrafanaReceiverType {
|
||||
grafanaCt++
|
||||
} else {
|
||||
amCt++
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TODO(owen-d): We may want to eventually support this, but short-circuiting for now
|
||||
// to reduce routing tree complexity.
|
||||
if grafanaCt > 0 && amCt > 0 {
|
||||
return nil, nil, fmt.Errorf("cannot mix Grafana Managed receivers with Alertmanager receivers in the same (non-root) routing tree")
|
||||
}
|
||||
|
||||
if grafanaCt > 0 {
|
||||
gRoutes = append(gRoutes, route)
|
||||
} else {
|
||||
amRoutes = append(amRoutes, route)
|
||||
}
|
||||
}
|
||||
|
||||
return gRoutes, amRoutes, nil
|
||||
}
|
||||
|
||||
func allReceivers(route *config.Route) (res []string) {
|
||||
res = append(res, route.Receiver)
|
||||
for _, subRoute := range route.Routes {
|
||||
res = append(res, allReceivers(subRoute)...)
|
||||
}
|
||||
return res
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
package validation
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/alerting-api/pkg/api"
|
||||
"github.com/prometheus/alertmanager/config"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_allReceivers(t *testing.T) {
|
||||
input := &config.Route{
|
||||
Receiver: "foo",
|
||||
Routes: []*config.Route{
|
||||
{
|
||||
Receiver: "bar",
|
||||
Routes: []*config.Route{
|
||||
{
|
||||
Receiver: "bazz",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Receiver: "buzz",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.Equal(t, []string{"foo", "bar", "bazz", "buzz"}, allReceivers(input))
|
||||
}
|
||||
|
||||
func Test_Splitroutes(t *testing.T) {
|
||||
receivers := map[string]api.ReceiverType{
|
||||
"am": api.AlertmanagerReceiverType,
|
||||
"graf": api.GrafanaReceiverType,
|
||||
}
|
||||
|
||||
for _, tc := range []struct {
|
||||
desc string
|
||||
input []*config.Route
|
||||
receivers map[string]api.ReceiverType
|
||||
err bool
|
||||
gRoutes, amRoutes []*config.Route
|
||||
}{
|
||||
{
|
||||
desc: "splits simple",
|
||||
input: []*config.Route{
|
||||
{
|
||||
Receiver: "am",
|
||||
},
|
||||
{
|
||||
Receiver: "graf",
|
||||
},
|
||||
},
|
||||
err: false,
|
||||
gRoutes: []*config.Route{
|
||||
{
|
||||
Receiver: "graf",
|
||||
},
|
||||
},
|
||||
amRoutes: []*config.Route{
|
||||
{
|
||||
Receiver: "am",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "splits nested",
|
||||
input: []*config.Route{
|
||||
{
|
||||
Receiver: "am",
|
||||
Routes: []*config.Route{
|
||||
{
|
||||
Receiver: "am",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Receiver: "graf",
|
||||
Routes: []*config.Route{
|
||||
{
|
||||
Receiver: "graf",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: false,
|
||||
gRoutes: []*config.Route{
|
||||
{
|
||||
Receiver: "graf",
|
||||
Routes: []*config.Route{
|
||||
{
|
||||
Receiver: "graf",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
amRoutes: []*config.Route{
|
||||
{
|
||||
Receiver: "am",
|
||||
Routes: []*config.Route{
|
||||
{
|
||||
Receiver: "am",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "errors undefined receiver",
|
||||
input: []*config.Route{
|
||||
{
|
||||
Receiver: "am",
|
||||
Routes: []*config.Route{
|
||||
{
|
||||
Receiver: "unmentioned",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
desc: "errors mixed",
|
||||
input: []*config.Route{
|
||||
{
|
||||
Receiver: "am",
|
||||
Routes: []*config.Route{
|
||||
{
|
||||
Receiver: "graf",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Receiver: "graf",
|
||||
Routes: []*config.Route{
|
||||
{
|
||||
Receiver: "graf",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: true,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
gRoutes, amRoutes, err := SplitRoutes(tc.input, receivers)
|
||||
if tc.err {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.Equal(t, tc.gRoutes, gRoutes)
|
||||
require.Equal(t, tc.amRoutes, amRoutes)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user