Skip to content

Commit

Permalink
Merge pull request #10 from logzio/feature/ms-teams-support
Browse files Browse the repository at this point in the history
[Feature] Add support for ms teams contact point
  • Loading branch information
yotamloe authored Jan 13, 2025
2 parents 4d38cbb + 6f77449 commit c5c8eb2
Show file tree
Hide file tree
Showing 11 changed files with 284 additions and 190 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
IMAGE_NAME := prometheus-alerts-migrator
IMAGE_TAG ?= v1.1.0
IMAGE_TAG ?= v1.2.0
DOCKER_REPO := logzio/$(IMAGE_NAME):$(IMAGE_TAG)


Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Before running this software, ensure you have:
- `Email`
- `Slack`
- `Pagerduty`
- `MS Teams`

More types will be supported in the future, If you have a specific request please post an issue with your request

Expand Down Expand Up @@ -167,6 +168,16 @@ data:


## Changelog
- v1.2.0
- Add support for MS Teams contact points
- Update dependencies:
- `prometheus/common`: `v0.60.1` -> `v0.61.0`
- `prometheus/prometheus`: `v0.55.0` -> `v0.301.0`
- `k8s.io/api`: `v0.31.2` -> `v0.32.0`
- `k8s.io/apimachinery`: `v0.31.2` -> `v0.32.0`
- `k8s.io/client-go`: `v0.31.2` -> `v0.32.0`
- Improve error handling In event handler creation
- Refactor import alias names to lowercase
- v1.1.0
- Add support for migrating alert rules groups
- Upgrade GoLang version to 1.23
Expand Down
5 changes: 3 additions & 2 deletions common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package common
import (
"flag"
"fmt"
"github.com/logzio/logzio_terraform_client/grafana_alerts"
grafanaalerts "github.com/logzio/logzio_terraform_client/grafana_alerts"
"github.com/prometheus/prometheus/model/rulefmt"
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/rest"
Expand All @@ -26,6 +26,7 @@ const (
TypeSlack = "slack"
TypeEmail = "email"
TypePagerDuty = "pagerduty" // # of letter indices fitting in 63 bits
TypeMsTeams = "teams"
)

var (
Expand Down Expand Up @@ -191,7 +192,7 @@ func CreateNameStub(cm *corev1.ConfigMap) string {
}

// IsAlertEqual compares two AlertRule objects for equality.
func IsAlertEqual(rule rulefmt.RuleNode, grafanaRule grafana_alerts.GrafanaAlertRule) bool {
func IsAlertEqual(rule rulefmt.RuleNode, grafanaRule grafanaalerts.GrafanaAlertRule) bool {
// Start with name comparison; if these don't match, they're definitely not equal.
if rule.Alert.Value != grafanaRule.Title {
return false
Expand Down
30 changes: 17 additions & 13 deletions controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/logzio/logzio_terraform_client/grafana_contact_points"
"github.com/logzio/prometheus-alerts-migrator/common"
"github.com/logzio/prometheus-alerts-migrator/logzio_alerts_client"
alert_manager_config "github.com/prometheus/alertmanager/config"
alertmanagerconfig "github.com/prometheus/alertmanager/config"
"github.com/prometheus/prometheus/model/rulefmt"
_ "github.com/prometheus/prometheus/promql/parser"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -97,7 +97,7 @@ func NewController(

controller.configmapEventRecorderFunc = controller.recordEventOnConfigMap
klog.Info("Setting up event handlers")
configmapInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
_, err := configmapInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: controller.enqueueConfigMap,
UpdateFunc: func(old, new interface{}) {
newCM := new.(*corev1.ConfigMap)
Expand All @@ -109,6 +109,10 @@ func NewController(
},
DeleteFunc: controller.enqueueConfigMap,
})
if err != nil {
klog.Errorf("Failed to set up event handlers: %v", err)
return nil
}

return controller
}
Expand Down Expand Up @@ -275,7 +279,7 @@ func (c *Controller) processAlertManagerConfigMaps(configmap *corev1.ConfigMap)
return err
}
// Creating maps for efficient lookups
receiversMap := make(map[string]alert_manager_config.Receiver)
receiversMap := make(map[string]alertmanagerconfig.Receiver)
for _, receiver := range receivers {
receiversMap[receiver.Name] = receiver
}
Expand Down Expand Up @@ -307,39 +311,39 @@ func (c *Controller) processAlertManagerConfigMaps(configmap *corev1.ConfigMap)
return nil
}

func (c *Controller) getClusterReceiversAndRoutes(configmap *corev1.ConfigMap) ([]alert_manager_config.Receiver, *alert_manager_config.Route, error) {
var receivers []alert_manager_config.Receiver
var routeTree alert_manager_config.Route
func (c *Controller) getClusterReceiversAndRoutes(configmap *corev1.ConfigMap) ([]alertmanagerconfig.Receiver, *alertmanagerconfig.Route, error) {
var receivers []alertmanagerconfig.Receiver
var routeTree alertmanagerconfig.Route
if c.isAlertManagerConfigMap(configmap) {
for _, value := range configmap.Data {
alertManagerConfig, err := alert_manager_config.Load(value)
config, err := alertmanagerconfig.Load(value)
if err != nil {
utilruntime.HandleError(fmt.Errorf("unable to load alert manager config; %s", err))
return nil, &alert_manager_config.Route{}, err
return nil, &alertmanagerconfig.Route{}, err
}
// Add prefix to distinguish between alert manager imported from alert manager and logz.io custom contact points
stub := common.CreateNameStub(configmap)
for _, receiver := range alertManagerConfig.Receivers {
for _, receiver := range config.Receivers {
receiver.Name = fmt.Sprintf("%s-%s-%s", c.envId, stub, receiver.Name)
receivers = append(receivers, receiver)

}
// Add prefix to routes to match with contact points
routeTree = *alertManagerConfig.Route
routeTree = *config.Route
routeTree.Receiver = fmt.Sprintf("%s-%s-%s", c.envId, stub, routeTree.Receiver)
for _, route := range routeTree.Routes {
route.Receiver = fmt.Sprintf("%s-%s-%s", c.envId, stub, route.Receiver)
}
// setting the `AlertManagerGlobalConfig` context for logzio grafana alerts client
c.logzioGrafanaAlertsClient.AlertManagerGlobalConfig = alertManagerConfig.Global
c.logzioGrafanaAlertsClient.AlertManagerGlobalConfig = config.Global
}
}
klog.Infof("Found %d receivers and %d routes, in %s", len(receivers), len(routeTree.Routes), configmap.Name)
return receivers, &routeTree, nil
}

// compareContactPoints
func (c *Controller) compareContactPoints(receiversMap map[string]alert_manager_config.Receiver, logzioContactPoints []grafana_contact_points.GrafanaContactPoint) (contactPointsToAdd, contactPointsToUpdate []alert_manager_config.Receiver, contactPointsToDelete []grafana_contact_points.GrafanaContactPoint) {
func (c *Controller) compareContactPoints(receiversMap map[string]alertmanagerconfig.Receiver, logzioContactPoints []grafana_contact_points.GrafanaContactPoint) (contactPointsToAdd, contactPointsToUpdate []alertmanagerconfig.Receiver, contactPointsToDelete []grafana_contact_points.GrafanaContactPoint) {
// Initialize a map with slices as values for Logz.io contact points
existingContactPoints := make(map[string][]grafana_contact_points.GrafanaContactPoint)
for _, contactPoint := range logzioContactPoints {
Expand Down Expand Up @@ -408,7 +412,7 @@ func (c *Controller) processAlertRules(rulesMap map[string]rulefmt.RuleNode, log
c.logzioGrafanaAlertsClient.UpdateRules(rulesToUpdate, logzioRulesMap, folderUid)
}
if len(rulesToDelete) > 0 {
c.logzioGrafanaAlertsClient.DeleteRules(rulesToDelete, folderUid)
c.logzioGrafanaAlertsClient.DeleteRules(rulesToDelete)
}
}

Expand Down
2 changes: 1 addition & 1 deletion controller/controller_e2e_cp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,6 @@ func TestControllerContactPointsE2E(t *testing.T) {
if err != nil {
t.Fatalf("Failed to get logzio contact points: %v", err)
}
assert.Equal(t, 13, len(logzioContactPoints))
assert.Equal(t, 14, len(logzioContactPoints))

}
2 changes: 1 addition & 1 deletion controller/controller_e2e_rules_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func cleanupLogzioAlerts(ctl Controller) {
if err != nil {
log.Fatalf("Failed to get logzio alerts: %v", err)
}
ctl.logzioGrafanaAlertsClient.DeleteRules(logzioAlerts, folderUid)
ctl.logzioGrafanaAlertsClient.DeleteRules(logzioAlerts)
}

// TestControllerE2E is the main function that runs the end-to-end test
Expand Down
73 changes: 29 additions & 44 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,93 +5,78 @@ go 1.23.0
require (
github.com/logzio/logzio_terraform_client v1.22.0
github.com/prometheus/alertmanager v0.27.0
github.com/prometheus/common v0.60.1
github.com/prometheus/prometheus v0.55.0
github.com/stretchr/testify v1.9.0
github.com/prometheus/common v0.61.0
github.com/prometheus/prometheus v0.301.0
github.com/stretchr/testify v1.10.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/api v0.31.2
k8s.io/apimachinery v0.31.2
k8s.io/client-go v0.31.2
k8s.io/api v0.32.0
k8s.io/apimachinery v0.32.0
k8s.io/client-go v0.32.0
k8s.io/klog/v2 v2.130.1
)

require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect
cloud.google.com/go/compute/metadata v0.6.0 // indirect
github.com/avast/retry-go v3.0.0+incompatible // indirect
github.com/aws/aws-sdk-go v1.55.5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dennwc/varint v1.0.0 // indirect
github.com/edsrzf/mmap-go v1.1.0 // indirect
github.com/edsrzf/mmap-go v1.2.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
github.com/go-openapi/swag v0.22.9 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grafana/regexp v0.0.0-20240518133315-a468a5bfb3bc // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/prometheus/client_golang v1.20.4 // indirect
github.com/prometheus/client_golang v1.20.5 // indirect
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common/sigv4 v0.1.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/otel v1.29.0 // indirect
go.opentelemetry.io/otel/metric v1.29.0 // indirect
go.opentelemetry.io/otel/trace v1.29.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.33.0 // indirect
go.opentelemetry.io/otel/metric v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.33.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/goleak v1.3.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
golang.org/x/net v0.29.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.24.0 // indirect
golang.org/x/text v0.18.0 // indirect
golang.org/x/time v0.6.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.34.2 // indirect
golang.org/x/net v0.33.0 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
golang.org/x/sys v0.28.0 // indirect
golang.org/x/term v0.27.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/time v0.8.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/protobuf v1.36.0 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
Loading

0 comments on commit c5c8eb2

Please sign in to comment.