Skip to content

Commit

Permalink
Select matching AlertmanagerConfigs
Browse files Browse the repository at this point in the history
This copies what the prometheus controller does for things like
ServiceMonitors.
  • Loading branch information
grdryn committed Sep 11, 2020
1 parent ab37127 commit 2895889
Showing 1 changed file with 71 additions and 1 deletion.
72 changes: 71 additions & 1 deletion pkg/alertmanager/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,13 @@ func (c *Operator) sync(ctx context.Context, key string) error {
}

func (c *Operator) provisionAlertmanagerConfiguration(ctx context.Context, am *monitoringv1.Alertmanager) error {
// If no AlertmanagerConfig selectors are configured, the user wants to
// manage configuration themselves.
if am.Spec.AlertmanagerConfigSelector == nil {
level.Debug(c.logger).Log("msg", ", no AlertmanagerConfig selector specified, leaving configuration unmanaged", "alertmanager", am.Name, "namespace", am.Namespace)
return nil
}

secretName := defaultConfigSecretName(am.Name)
if am.Spec.ConfigSecret != "" {
secretName = am.Spec.ConfigSecret
Expand Down Expand Up @@ -679,7 +686,12 @@ func (c *Operator) provisionAlertmanagerConfiguration(ctx context.Context, am *m
return errors.New("default route must be configured")
}

// build routes, receivers and inhibit rules from AlertmanagerConfigs here
amcs, err := c.selectAlertManagerConfigs(am)
if err != nil {
return errors.Wrap(err, "selecting AlertmanagerConfigs failed")
}

level.Info(c.logger).Log("msg", "amcs", "amcs", amcs, "namespace", am.Namespace, "alertmanager", am.Name)

if foundReceivers {
// just append receivrs from AlertmanagerConfig CRs, otherwise must first create receivers field
Expand All @@ -692,6 +704,64 @@ func (c *Operator) provisionAlertmanagerConfiguration(ctx context.Context, am *m
return nil
}

func (c *Operator) selectAlertManagerConfigs(am *monitoringv1.Alertmanager) (map[string]*monitoringv1.AlertmanagerConfig, error) {
namespaces := []string{}
// Selectors (<namespace>/<name>) might overlap. Deduplicate them along the keyFunc.
res := make(map[string]*monitoringv1.AlertmanagerConfig)

amConfigSelector, err := metav1.LabelSelectorAsSelector(am.Spec.AlertmanagerConfigSelector)
if err != nil {
return nil, err
}

// If 'AlertmanagerConfigNamespaceSelector' is nil, only check own namespace.
if am.Spec.AlertmanagerConfigNamespaceSelector == nil {
namespaces = append(namespaces, am.Namespace)
} else {
amConfigNSSelector, err := metav1.LabelSelectorAsSelector(am.Spec.AlertmanagerConfigNamespaceSelector)
if err != nil {
return nil, err
}

namespaces, err = c.listMatchingNamespaces(amConfigNSSelector)
if err != nil {
return nil, err
}
}

level.Debug(c.logger).Log("msg", "filtering namespaces to select AlertmanagerConfigs from", "namespaces", strings.Join(namespaces, ","), "namespace", am.Namespace, "alertmanager", am.Name)

for _, ns := range namespaces {
c.alrtCfgInfs.ListAllByNamespace(ns, amConfigSelector, func(obj interface{}) {
k, ok := c.keyFunc(obj)
if ok {
res[k] = obj.(*monitoringv1.AlertmanagerConfig)
}
})
}

alertmanagerConfigs := []string{}
for k := range res {
alertmanagerConfigs = append(alertmanagerConfigs, k)
}
level.Debug(c.logger).Log("msg", "selected AlertmanagerConfigs", "aletmanagerconfigs", strings.Join(alertmanagerConfigs, ","), "namespace", am.Namespace, "prometheus", am.Name)

return res, nil
}

// listMatchingNamespaces lists all the namespaces that match the provided
// selector.
func (c *Operator) listMatchingNamespaces(selector labels.Selector) ([]string, error) {
var ns []string
err := cache.ListAll(c.nsAlrtInf.GetStore(), selector, func(obj interface{}) {
ns = append(ns, obj.(*v1.Namespace).Name)
})
if err != nil {
return nil, errors.Wrap(err, "failed to list namespaces")
}
return ns, nil
}

//checkAlertmanagerSpecDeprecation checks for deprecated fields in the prometheus spec and logs a warning if applicable
func checkAlertmanagerSpecDeprecation(key string, a *monitoringv1.Alertmanager, logger log.Logger) {
deprecationWarningf := "alertmanager key=%v, field %v is deprecated, '%v' field should be used instead"
Expand Down

0 comments on commit 2895889

Please sign in to comment.