From 18ae819cbea519fc0e7ddf3a1043888405ba1172 Mon Sep 17 00:00:00 2001 From: Owen Diehl Date: Fri, 26 Feb 2021 11:29:22 -0500 Subject: [PATCH 1/3] single route per Alerting config --- Makefile | 2 +- README.md | 1 - pkg/api/alertmanager.go | 40 +++----- pkg/api/alertmanager_test.go | 174 ++++++++--------------------------- 4 files changed, 55 insertions(+), 162 deletions(-) diff --git a/Makefile b/Makefile index 8ec0e88b4ea..549012eec06 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ GO_PKG_FILES = $(shell find $(PKG_DIR) -name *.go -print) spec.json: $(GO_PKG_FILES) - swagger generate spec -m -w $(PKG_DIR) | jq 'del(.definitions.ApiAlertingConfig.properties.route)' > $@ + swagger generate spec -m -w $(PKG_DIR) -o $@ .PHONY: openapi diff --git a/README.md b/README.md index b47529aff8c..02e11912023 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,3 @@ This repo aims to define the unified alerting API as code. It generates OpenAPI ## Requires - [go-swagger](https://github.com/go-swagger/go-swagger) - - [jq](https://stedolan.github.io/jq/) diff --git a/pkg/api/alertmanager.go b/pkg/api/alertmanager.go index 9d3f17025b6..5ca05a7d68e 100644 --- a/pkg/api/alertmanager.go +++ b/pkg/api/alertmanager.go @@ -180,12 +180,6 @@ type AlertingConfigResponse struct { type ApiAlertingConfig struct { config.Config - // TODO: PR a followup to https://github.com/go-swagger/go-swagger/pull/1527 in order to allow - // explicitly ignoring embedded fields. In the meantime, these are hackily removed in our make targets via `jq` - - AlertManagerRoute *config.Route `yaml:"alertmanager_route,omitempty" json:"alertmanager_route,omitempty"` - GrafanaManagedRoute *config.Route `yaml:"grafana_managed_route,omitempty" json:"grafana_managed_route,omitempty"` - // Override with our superset receiver type Receivers []*ApiReceiver `yaml:"receivers,omitempty" json:"receivers,omitempty"` } @@ -201,32 +195,28 @@ func (c *ApiAlertingConfig) UnmarshalJSON(b []byte) error { // validate ensures that the two routing trees use the correct receiver types. func (c *ApiAlertingConfig) validate() error { - receivers := make(map[string]ReceiverType, len(c.Receivers)) + receivers := make(map[string]struct{}, len(c.Receivers)) + var hasGrafReceivers, hasAMReceivers bool for _, r := range c.Receivers { - receivers[r.Name] = r.Type() + receivers[r.Name] = struct{}{} + switch r.Type() { + case GrafanaReceiverType: + hasGrafReceivers = true + case AlertmanagerReceiverType: + hasAMReceivers = true + } } - for _, receiver := range AllReceivers(c.GrafanaManagedRoute) { - t, ok := receivers[receiver] + if hasGrafReceivers && hasAMReceivers { + return fmt.Errorf("cannot mix Alertmanager & Grafana receiver types") + } + + for _, receiver := range AllReceivers(c.Route) { + _, ok := receivers[receiver] if !ok { return fmt.Errorf("unexpected receiver (%s) is undefined", receiver) } - if t != GrafanaReceiverType { - return fmt.Errorf("unexpected receiver (%s): cannot use Alertmanager receiver types in Grafana managed routes", receiver) - } - - } - - for _, receiver := range AllReceivers(c.AlertManagerRoute) { - t, ok := receivers[receiver] - if !ok { - return fmt.Errorf("unexpected receiver (%s) is undefined", receiver) - } - if t != AlertmanagerReceiverType { - return fmt.Errorf("unexpected receiver (%s): cannot use Grafana receiver types in non-Grafana managed routes", receiver) - } - } return nil diff --git a/pkg/api/alertmanager_test.go b/pkg/api/alertmanager_test.go index a551e3775d3..06ead584531 100644 --- a/pkg/api/alertmanager_test.go +++ b/pkg/api/alertmanager_test.go @@ -92,22 +92,15 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) { err bool }{ { - desc: "success", + desc: "success am", input: ApiAlertingConfig{ - Config: config.Config{}, - AlertManagerRoute: &config.Route{ - Receiver: "am", - Routes: []*config.Route{ - { - Receiver: "am", - }, - }, - }, - GrafanaManagedRoute: &config.Route{ - Receiver: "graf", - Routes: []*config.Route{ - { - Receiver: "graf", + Config: config.Config{ + Route: &config.Route{ + Receiver: "am", + Routes: []*config.Route{ + { + Receiver: "am", + }, }, }, }, @@ -118,6 +111,23 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) { EmailConfigs: []*config.EmailConfig{{}}, }, }, + }, + }, + }, + { + desc: "success graf", + input: ApiAlertingConfig{ + Config: config.Config{ + Route: &config.Route{ + Receiver: "graf", + Routes: []*config.Route{ + { + Receiver: "graf", + }, + }, + }, + }, + Receivers: []*ApiReceiver{ { Receiver: config.Receiver{ Name: "graf", @@ -132,20 +142,13 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) { { desc: "failure undefined am receiver", input: ApiAlertingConfig{ - Config: config.Config{}, - AlertManagerRoute: &config.Route{ - Receiver: "am", - Routes: []*config.Route{ - { - Receiver: "unmentioned", - }, - }, - }, - GrafanaManagedRoute: &config.Route{ - Receiver: "graf", - Routes: []*config.Route{ - { - Receiver: "graf", + Config: config.Config{ + Route: &config.Route{ + Receiver: "am", + Routes: []*config.Route{ + { + Receiver: "unmentioned", + }, }, }, }, @@ -156,14 +159,6 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) { EmailConfigs: []*config.EmailConfig{{}}, }, }, - { - Receiver: config.Receiver{ - Name: "graf", - }, - GrafanaReceivers: GrafanaReceivers{ - GrafanaManagedReceivers: []*GrafanaReceiver{{}}, - }, - }, }, }, err: true, @@ -171,108 +166,17 @@ func Test_ApiAlertingConfig_Marshaling(t *testing.T) { { desc: "failure undefined graf receiver", input: ApiAlertingConfig{ - Config: config.Config{}, - AlertManagerRoute: &config.Route{ - Receiver: "am", - Routes: []*config.Route{ - { - Receiver: "am", - }, - }, - }, - GrafanaManagedRoute: &config.Route{ - Receiver: "graf", - Routes: []*config.Route{ - { - Receiver: "unmentioned", + Config: config.Config{ + Route: &config.Route{ + Receiver: "graf", + Routes: []*config.Route{ + { + Receiver: "unmentioned", + }, }, }, }, Receivers: []*ApiReceiver{ - { - Receiver: config.Receiver{ - Name: "am", - EmailConfigs: []*config.EmailConfig{{}}, - }, - }, - { - Receiver: config.Receiver{ - Name: "graf", - }, - GrafanaReceivers: GrafanaReceivers{ - GrafanaManagedReceivers: []*GrafanaReceiver{{}}, - }, - }, - }, - }, - err: true, - }, - { - desc: "failure mixed AM in Grafana", - input: ApiAlertingConfig{ - Config: config.Config{}, - AlertManagerRoute: &config.Route{ - Receiver: "am", - Routes: []*config.Route{ - { - Receiver: "am", - }, - }, - }, - GrafanaManagedRoute: &config.Route{ - Receiver: "graf", - Routes: []*config.Route{ - { - Receiver: "am", - }, - }, - }, - Receivers: []*ApiReceiver{ - { - Receiver: config.Receiver{ - Name: "am", - EmailConfigs: []*config.EmailConfig{{}}, - }, - }, - { - Receiver: config.Receiver{ - Name: "graf", - }, - GrafanaReceivers: GrafanaReceivers{ - GrafanaManagedReceivers: []*GrafanaReceiver{{}}, - }, - }, - }, - }, - err: true, - }, - { - desc: "failure mixed Grafana in AM", - input: ApiAlertingConfig{ - Config: config.Config{}, - AlertManagerRoute: &config.Route{ - Receiver: "am", - Routes: []*config.Route{ - { - Receiver: "graf", - }, - }, - }, - GrafanaManagedRoute: &config.Route{ - Receiver: "graf", - Routes: []*config.Route{ - { - Receiver: "graf", - }, - }, - }, - Receivers: []*ApiReceiver{ - { - Receiver: config.Receiver{ - Name: "am", - EmailConfigs: []*config.EmailConfig{{}}, - }, - }, { Receiver: config.Receiver{ Name: "graf", From 1b4946d74208e296ad2ae0062763193e68c0c4f8 Mon Sep 17 00:00:00 2001 From: Owen Diehl Date: Fri, 26 Feb 2021 11:30:15 -0500 Subject: [PATCH 2/3] removes unused routing pkg --- pkg/routing/alertconfig.go | 48 -------------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 pkg/routing/alertconfig.go diff --git a/pkg/routing/alertconfig.go b/pkg/routing/alertconfig.go deleted file mode 100644 index 45f486efffe..00000000000 --- a/pkg/routing/alertconfig.go +++ /dev/null @@ -1,48 +0,0 @@ -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 -} From be6bba95039a8f5c69c1221a568419e3077e9d27 Mon Sep 17 00:00:00 2001 From: Owen Diehl Date: Fri, 26 Feb 2021 11:31:30 -0500 Subject: [PATCH 3/3] regens spec --- spec.json | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/spec.json b/spec.json index b631bbb6280..08c89c88d8b 100644 --- a/spec.json +++ b/spec.json @@ -1021,15 +1021,9 @@ "ApiAlertingConfig": { "type": "object", "properties": { - "alertmanager_route": { - "$ref": "#/definitions/Route" - }, "global": { "$ref": "#/definitions/GlobalConfig" }, - "grafana_managed_route": { - "$ref": "#/definitions/Route" - }, "inhibit_rules": { "type": "array", "items": { @@ -1045,6 +1039,9 @@ }, "x-go-name": "Receivers" }, + "route": { + "$ref": "#/definitions/Route" + }, "templates": { "type": "array", "items": { @@ -1736,7 +1733,7 @@ "properties": { "Expr": { "type": "string", - "example": "(node_filesystem_avail_bytes{fstype!=\"\",job=\"integrations/node_exporter\"} node_filesystem_size_bytes{fstype!=\"\",job=\"integrations/node_exporter\"} * 100 < 5 and node_filesystem_readonly{fstype!=\"\",job=\"integrations/node_exporter\"} == 0)" + "example": "(node_filesystem_avail_bytes{fstype!=\"\",job=\"integrations/node_exporter\"} node_filesystem_size_bytes{fstype!=\"\",job=\"integrations/node_exporter\"} * 100 \u003c 5 and node_filesystem_readonly{fstype!=\"\",job=\"integrations/node_exporter\"} == 0)" }, "datasourceUid": { "description": "DatasourceUID is required if the query will be sent to grafana to be executed", @@ -3561,4 +3558,4 @@ "type": "basic" } } -} +} \ No newline at end of file