diff --git a/cmd/karma/proxy_test.go b/cmd/karma/proxy_test.go index d0757a8df..5e97c7190 100644 --- a/cmd/karma/proxy_test.go +++ b/cmd/karma/proxy_test.go @@ -52,6 +52,20 @@ var proxyTests = []proxyTest{ code: 200, response: "{\"status\":\"success\"}", }, + { + method: "POST", + localPath: "/proxy/alertmanager/dummy/api/v2/silences", + upstreamURI: "http://localhost:9093/api/v2/silences", + code: 200, + response: "{\"status\":\"success\",\"data\":{\"silenceId\":\"d8a61ca8-ee2e-4076-999f-276f1e986bf3\"}}", + }, + { + method: "DELETE", + localPath: "/proxy/alertmanager/dummy/api/v2/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3", + upstreamURI: "http://localhost:9093/api/v2/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3", + code: 200, + response: "{\"status\":\"success\"}", + }, // invalid alertmanager name { method: "POST", @@ -67,6 +81,20 @@ var proxyTests = []proxyTest{ code: 404, response: "404 page not found", }, + { + method: "POST", + localPath: "/proxy/alertmanager/INVALID/api/v2/silences", + upstreamURI: "", + code: 404, + response: "404 page not found", + }, + { + method: "DELETE", + localPath: "/proxy/alertmanager/INVALID/api/v2/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3", + upstreamURI: "http://localhost:9093/api/v2/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3", + code: 404, + response: "404 page not found", + }, // valid alertmanager name, but invalid method { method: "GET", @@ -82,6 +110,20 @@ var proxyTests = []proxyTest{ code: 404, response: "404 page not found", }, + { + method: "GET", + localPath: "/proxy/alertmanager/dummy/api/v2/silences", + upstreamURI: "", + code: 404, + response: "404 page not found", + }, + { + method: "GET", + localPath: "/proxy/alertmanager/dummy/api/v2/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3", + upstreamURI: "http://localhost:9093/api/v2/silence/d8a61ca8-ee2e-4076-999f-276f1e986bf3", + code: 404, + response: "404 page not found", + }, } func TestProxy(t *testing.T) { @@ -135,6 +177,7 @@ type proxyHeaderTest struct { } var proxyHeaderTests = []proxyHeaderTest{ + // API v1 { method: "POST", localPath: "/proxy/alertmanager/dummy/api/v1/silences", @@ -171,6 +214,43 @@ var proxyHeaderTests = []proxyHeaderTest{ authUser: "foo", authPass: "", }, + // API v2 + { + method: "POST", + localPath: "/proxy/alertmanager/dummy/api/v2/silences", + upstreamURI: "http://localhost:9093/api/v2/silences", + code: 200, + alertmanagerURI: "http://localhost:9093", + alertmanagerHost: "localhost:9093", + }, + { + method: "POST", + localPath: "/proxy/alertmanager/dummy/api/v2/silences", + upstreamURI: "http://alertmanager.example.com/api/v2/silences", + code: 200, + alertmanagerURI: "http://alertmanager.example.com", + alertmanagerHost: "alertmanager.example.com", + }, + { + method: "POST", + localPath: "/proxy/alertmanager/dummy/api/v2/silences", + upstreamURI: "http://alertmanager.example.com/api/v2/silences", + code: 200, + alertmanagerURI: "http://foo:bar@alertmanager.example.com", + alertmanagerHost: "alertmanager.example.com", + authUser: "foo", + authPass: "bar", + }, + { + method: "POST", + localPath: "/proxy/alertmanager/dummy/api/v2/silences", + upstreamURI: "http://alertmanager.example.com/api/v2/silences", + code: 200, + alertmanagerURI: "http://foo@alertmanager.example.com", + alertmanagerHost: "alertmanager.example.com", + authUser: "foo", + authPass: "", + }, } func TestProxyHeaders(t *testing.T) { diff --git a/internal/alertmanager/mapper.go b/internal/alertmanager/mapper.go index e0ebadc69..820571547 100644 --- a/internal/alertmanager/mapper.go +++ b/internal/alertmanager/mapper.go @@ -6,7 +6,6 @@ import ( v017 "github.com/prymitive/karma/internal/mapper/v017" v04 "github.com/prymitive/karma/internal/mapper/v04" v05 "github.com/prymitive/karma/internal/mapper/v05" - v061 "github.com/prymitive/karma/internal/mapper/v061" v062 "github.com/prymitive/karma/internal/mapper/v062" ) @@ -14,7 +13,6 @@ import ( func init() { mapper.RegisterAlertMapper(v04.AlertMapper{}) mapper.RegisterAlertMapper(v05.AlertMapper{}) - mapper.RegisterAlertMapper(v061.AlertMapper{}) mapper.RegisterAlertMapper(v062.AlertMapper{}) mapper.RegisterSilenceMapper(v04.SilenceMapper{}) mapper.RegisterSilenceMapper(v05.SilenceMapper{}) diff --git a/internal/mapper/v061/alerts.go b/internal/mapper/v061/alerts.go deleted file mode 100644 index 62a3592b3..000000000 --- a/internal/mapper/v061/alerts.go +++ /dev/null @@ -1,144 +0,0 @@ -// Package v061 package implements support for interacting with -// Alertmanager 0.6.1 -// Collected data will be mapped to karma internal schema defined the -// karma/models package -// This file defines Alertmanager alerts mapping -package v061 - -import ( - "encoding/json" - "errors" - "io" - "sort" - "time" - - "github.com/Masterminds/semver/v3" - "github.com/prymitive/karma/internal/mapper" - "github.com/prymitive/karma/internal/models" - "github.com/prymitive/karma/internal/uri" -) - -type alert struct { - Annotations map[string]string `json:"annotations"` - Labels map[string]string `json:"labels"` - StartsAt time.Time `json:"startsAt"` - GeneratorURL string `json:"generatorURL"` - Status string `json:"Status"` - SilencedBy []string `json:"silencedBy"` - InhibitedBy []string `json:"inhibitedBy"` -} - -type alertsGroups struct { - Labels map[string]string `json:"labels"` - Blocks []struct { - Alerts []alert `json:"alerts"` - RouteOps struct { - Receiver string `json:"receiver"` - } `json:"routeOpts"` - } `json:"blocks"` -} - -type alertsGroupsAPISchema struct { - Status string `json:"status"` - Data []alertsGroups `json:"data"` - Error string `json:"error"` -} - -type alertsGroupReceiver struct { - Name string - Groups []models.AlertGroup -} - -// AlertMapper implements Alertmanager API schema -type AlertMapper struct { - mapper.AlertMapper -} - -// AbsoluteURL for alerts API endpoint this mapper supports -func (m AlertMapper) AbsoluteURL(baseURI string) (string, error) { - return uri.JoinURL(baseURI, "api/v1/alerts/groups") -} - -// QueryArgs for HTTP requests send to the Alertmanager API endpoint -func (m AlertMapper) QueryArgs() string { - return "" -} - -// IsSupported returns true if given version string is supported -func (m AlertMapper) IsSupported(version string) bool { - versionRange, err := semver.NewConstraint("=0.6.1") - if err != nil { - panic(err) - } - return versionRange.Check(semver.MustParse(version)) -} - -// IsOpenAPI returns true is remote Alertmanager uses OpenAPI -func (m AlertMapper) IsOpenAPI() bool { - return false -} - -// Decode Alertmanager API response body and return karma model instances -func (m AlertMapper) Decode(source io.ReadCloser) ([]models.AlertGroup, error) { - groups := []models.AlertGroup{} - receivers := map[string]alertsGroupReceiver{} - resp := alertsGroupsAPISchema{} - - defer source.Close() - err := json.NewDecoder(source).Decode(&resp) - if err != nil { - return groups, err - } - - if resp.Status != mapper.AlertmanagerStatusString { - return groups, errors.New(resp.Error) - } - - for _, d := range resp.Data { - for _, b := range d.Blocks { - rcv, found := receivers[b.RouteOps.Receiver] - if !found { - rcv = alertsGroupReceiver{ - Name: b.RouteOps.Receiver, - } - receivers[b.RouteOps.Receiver] = rcv - } - alertList := models.AlertList{} - for _, a := range b.Alerts { - inhibitedBy := []string{} - if a.InhibitedBy != nil { - inhibitedBy = a.InhibitedBy - } - silencedBy := []string{} - if a.SilencedBy != nil { - silencedBy = a.SilencedBy - } - a := models.Alert{ - Receiver: rcv.Name, - Annotations: models.AnnotationsFromMap(a.Annotations), - Labels: a.Labels, - StartsAt: a.StartsAt, - GeneratorURL: a.GeneratorURL, - State: a.Status, - InhibitedBy: inhibitedBy, - SilencedBy: silencedBy, - } - sort.Strings(a.InhibitedBy) - sort.Strings(a.SilencedBy) - a.UpdateFingerprints() - alertList = append(alertList, a) - } - ug := models.AlertGroup{ - Receiver: rcv.Name, - Labels: d.Labels, - Alerts: alertList, - } - rcv.Groups = append(rcv.Groups, ug) - receivers[rcv.Name] = rcv - } - } - for _, rcv := range receivers { - groups = append(groups, rcv.Groups...) - } - return groups, nil -} diff --git a/scripts/gocover.sh b/scripts/gocover.sh index fd991473d..c416b3333 100755 --- a/scripts/gocover.sh +++ b/scripts/gocover.sh @@ -4,10 +4,10 @@ set -e echo "" > coverage.txt -for d in $(go list ./... | grep -v github.com/prymitive/karma/internal/mapper); do +for d in $(go list ./... | grep -vE 'prymitive/karma/internal/mapper/v017/(client|models)'); do go test \ -coverprofile=profile.out \ - -coverpkg=$(go list ./... | grep -v github.com/prymitive/karma/internal/mapper | tr '\n' ',') \ + -coverpkg=$(go list ./... | grep -vE 'prymitive/karma/internal/mapper/v017/(client|models)' | tr '\n' ',') \ $d 2>&1 | grep -v 'warning: no packages being tested depend on matches for pattern' if [ -f profile.out ]; then cat profile.out >> coverage.txt