From b9de72fc489f37d1bd6b83132226846ee6b11bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Tue, 9 May 2017 21:52:39 +0100 Subject: [PATCH] Add support for Alertmanager 0.6.2 Minor changes in the API. --- alertmanager/alertmanager.go | 2 + mapper/v061/alerts.go | 2 +- mapper/v062/alerts.go | 110 +++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 mapper/v062/alerts.go diff --git a/alertmanager/alertmanager.go b/alertmanager/alertmanager.go index e9cff4adc..c48fe5723 100644 --- a/alertmanager/alertmanager.go +++ b/alertmanager/alertmanager.go @@ -7,6 +7,7 @@ import ( "github.com/cloudflare/unsee/mapper/v04" "github.com/cloudflare/unsee/mapper/v05" "github.com/cloudflare/unsee/mapper/v061" + "github.com/cloudflare/unsee/mapper/v062" "github.com/cloudflare/unsee/models" log "github.com/Sirupsen/logrus" @@ -17,6 +18,7 @@ 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/mapper/v061/alerts.go b/mapper/v061/alerts.go index bd88cfa92..e54cc03c4 100644 --- a/mapper/v061/alerts.go +++ b/mapper/v061/alerts.go @@ -47,7 +47,7 @@ type AlertMapper struct { // IsSupported returns true if given version string is supported func (m AlertMapper) IsSupported(version string) bool { - versionRange := semver.MustParseRange(">=0.6.1") + versionRange := semver.MustParseRange("=0.6.1") return versionRange(semver.MustParse(version)) } diff --git a/mapper/v062/alerts.go b/mapper/v062/alerts.go new file mode 100644 index 000000000..2128e8a96 --- /dev/null +++ b/mapper/v062/alerts.go @@ -0,0 +1,110 @@ +// Package v062 package implements support for interacting with +// Alertmanager 0.6.2 +// Collected data will be mapped to unsee internal schema defined the +// unsee/models package +// This file defines Alertmanager alerts mapping +package v062 + +import ( + "errors" + "time" + + "github.com/blang/semver" + "github.com/cloudflare/unsee/config" + "github.com/cloudflare/unsee/mapper" + "github.com/cloudflare/unsee/models" + "github.com/cloudflare/unsee/transport" +) + +type alertStatus struct { + State string `json:"state"` + SilencedBy []string `json:"silencedBy"` + InhibitedBy []string `json:"inhibitedBy"` +} + +type alert struct { + Annotations map[string]string `json:"annotations"` + Labels map[string]string `json:"labels"` + StartsAt time.Time `json:"startsAt"` + EndsAt time.Time `json:"endsAt"` + GeneratorURL string `json:"generatorURL"` + Status alertStatus `json:"status"` +} + +type alertsGroups struct { + Labels map[string]string `json:"labels"` + Blocks []struct { + Alerts []alert `json:"alerts"` + } `json:"blocks"` +} + +type alertsGroupsAPISchema struct { + Status string `json:"status"` + Groups []alertsGroups `json:"data"` + Error string `json:"error"` +} + +// AlertMapper implements Alertmanager API schema +type AlertMapper struct { + mapper.AlertMapper +} + +// IsSupported returns true if given version string is supported +func (m AlertMapper) IsSupported(version string) bool { + versionRange := semver.MustParseRange(">=0.6.2") + return versionRange(semver.MustParse(version)) +} + +// GetAlerts will make a request to Alertmanager API and parse the response +// It will only return alerts or error (if any) +func (m AlertMapper) GetAlerts() ([]models.AlertGroup, error) { + groups := []models.AlertGroup{} + resp := alertsGroupsAPISchema{} + + url, err := transport.JoinURL(config.Config.AlertmanagerURI, "api/v1/alerts/groups") + if err != nil { + return groups, err + } + + err = transport.ReadJSON(url, config.Config.AlertmanagerTimeout, &resp) + if err != nil { + return groups, err + } + + if resp.Status != "success" { + return groups, errors.New(resp.Error) + } + + for _, g := range resp.Groups { + alertList := models.AlertList{} + for _, b := range g.Blocks { + for _, a := range b.Alerts { + inhibitedBy := []string{} + if a.Status.InhibitedBy != nil { + inhibitedBy = a.Status.InhibitedBy + } + silencedBy := []string{} + if a.Status.SilencedBy != nil { + silencedBy = a.Status.SilencedBy + } + us := models.Alert{ + Annotations: a.Annotations, + Labels: a.Labels, + StartsAt: a.StartsAt, + EndsAt: a.EndsAt, + GeneratorURL: a.GeneratorURL, + Status: a.Status.State, + InhibitedBy: inhibitedBy, + SilencedBy: silencedBy, + } + alertList = append(alertList, us) + } + } + ug := models.AlertGroup{ + Labels: g.Labels, + Alerts: alertList, + } + groups = append(groups, ug) + } + return groups, nil +}