diff --git a/CHANGELOG.md b/CHANGELOG.md index 81a10cd3b1..f0e2ee43f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,8 @@ Main (unreleased) - Fix the `prometheus.operator.*` components internal scrape manager now having a way to enable ingesting native histograms. (@dehaansa) +- [`mimir.alerts.kubernetes`] Fixed a bug which caused Alloy to crash when using a Kubernetes secret or configmap in the AlertmanagerConfig CRD. (@synthe102) + v1.12.0 ----------------- diff --git a/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/expected_1.yml b/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/expected_1.yml index 5b32e9a83f..78e74ef520 100644 --- a/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/expected_1.yml +++ b/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/expected_1.yml @@ -34,6 +34,17 @@ alertmanager_config: | - name: alloy-namespace/global-config/myreceiver - name: testing/alertmgr-config1/null - name: testing/alertmgr-config1/myamc + slack_configs: + - api_url: https://val1.com + fields: + - title: title + value: value` + actions: + - type: type + text: text + name: my-action + confirm: + text: text webhook_configs: - url: http://test.url http_config: diff --git a/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/expected_2.yml b/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/expected_2.yml index 0b6890638a..e51488d992 100644 --- a/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/expected_2.yml +++ b/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/expected_2.yml @@ -25,6 +25,17 @@ alertmanager_config: | - name: alloy-namespace/global-config/myreceiver - name: testing/alertmgr-config1/null - name: testing/alertmgr-config1/myamc + slack_configs: + - api_url: https://val1.com + fields: + - title: title + value: value` + actions: + - type: type + text: text + name: my-action + confirm: + text: text webhook_configs: - url: http://test.url http_config: diff --git a/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/kubernetes.yml b/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/kubernetes.yml index d98fa150ab..2f5e73fddc 100644 --- a/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/kubernetes.yml +++ b/internal/cmd/integration-tests-k8s/tests/mimir-alerts-kubernetes/testdata/kubernetes.yml @@ -17,7 +17,7 @@ metadata: name: grafana-alloy rules: - apiGroups: [""] - resources: ["namespaces", "configmaps"] + resources: ["namespaces", "configmaps", "secrets"] verbs: ["get", "list", "watch"] - apiGroups: ["monitoring.coreos.com"] resources: ["alertmanagerconfigs"] @@ -139,6 +139,14 @@ data: templates: - 'default_template' --- +apiVersion: v1 +kind: Secret +metadata: + name: s-receiver-api-url + namespace: testing +stringData: + api-url: https://val1.com +--- apiVersion: monitoring.coreos.com/v1alpha1 kind: AlertmanagerConfig metadata: @@ -159,6 +167,19 @@ spec: - url: http://test.url httpConfig: followRedirects: true + slackConfigs: + - apiURL: + key: api-url + name: "s-receiver-api-url" + actions: + - type: type + text: text + name: my-action + confirm: + text: text + fields: + - title: title + value: value` --- apiVersion: monitoring.coreos.com/v1alpha1 kind: AlertmanagerConfig diff --git a/internal/component/mimir/alerts/kubernetes/alerts.go b/internal/component/mimir/alerts/kubernetes/alerts.go index fe2cffc46f..d2bc3baa7f 100644 --- a/internal/component/mimir/alerts/kubernetes/alerts.go +++ b/internal/component/mimir/alerts/kubernetes/alerts.go @@ -28,6 +28,7 @@ import ( "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" + "github.com/prometheus-operator/prometheus-operator/pkg/assets" promExternalVersions "github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions" promListers_v1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/client/listers/monitoring/v1alpha1" promVersioned "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned" @@ -233,8 +234,9 @@ func (c *Component) Startup(ctx context.Context) error { if err != nil { return fmt.Errorf("failed to unmarshal global config: %w", err) } + sb := assets.NewStoreBuilder(c.k8sClient.CoreV1(), c.k8sClient.CoreV1()) - c.eventProcessor = c.newEventProcessor(queue, informerStopChan, namespaceLister, cfgLister, *baseCfg) + c.eventProcessor = c.newEventProcessor(queue, informerStopChan, namespaceLister, cfgLister, *baseCfg, sb) go c.eventProcessor.run(ctx) return nil @@ -346,7 +348,7 @@ func (c *Component) startConfigInformer(queue workqueue.TypedRateLimitingInterfa func (c *Component) newEventProcessor(queue workqueue.TypedRateLimitingInterface[commonK8s.Event], stopChan chan struct{}, namespaceLister coreListers.NamespaceLister, cfgLister promListers_v1alpha1.AlertmanagerConfigLister, - baseCfg alertmgr_cfg.Config) *eventProcessor { + baseCfg alertmgr_cfg.Config, sb *assets.StoreBuilder) *eventProcessor { // Deep copy to make sure that a change in arguments won't immediately propagate to the event processor. templateFiles := make(map[string]string, len(c.args.TemplateFiles)) @@ -366,5 +368,6 @@ func (c *Component) newEventProcessor(queue workqueue.TypedRateLimitingInterface logger: c.log, kclient: c.k8sClient, templateFiles: templateFiles, + storeBuilder: sb, } } diff --git a/internal/component/mimir/alerts/kubernetes/events.go b/internal/component/mimir/alerts/kubernetes/events.go index 3bcf528cad..271cee9e6b 100644 --- a/internal/component/mimir/alerts/kubernetes/events.go +++ b/internal/component/mimir/alerts/kubernetes/events.go @@ -41,6 +41,7 @@ type eventProcessor struct { namespaceSelector labels.Selector cfgSelector labels.Selector kclient go_k8s.Interface + storeBuilder *assets.StoreBuilder baseCfg alertmgr_cfg.Config templateFiles map[string]string @@ -253,7 +254,7 @@ func (e *eventProcessor) desiredStateFromKubernetes(ctx context.Context) (*alert } } - cfg, err := e.provisionAlertmanagerConfiguration(ctx, amConfigs, nil) + cfg, err := e.provisionAlertmanagerConfiguration(ctx, amConfigs, e.storeBuilder) if err != nil { return nil, fmt.Errorf("failed to provision Alertmanager configuration: %w", err) } diff --git a/internal/component/mimir/alerts/kubernetes/events_test.go b/internal/component/mimir/alerts/kubernetes/events_test.go index ce5da66856..b8631bd864 100644 --- a/internal/component/mimir/alerts/kubernetes/events_test.go +++ b/internal/component/mimir/alerts/kubernetes/events_test.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/alloy/internal/mimir/alertmanager" monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" monitoringv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" + "github.com/prometheus-operator/prometheus-operator/pkg/assets" promListers_v1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/client/listers/monitoring/v1alpha1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -20,6 +21,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes/fake" coreListers "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/util/workqueue" @@ -113,7 +115,20 @@ spec: webhookConfigs: - url: http://test.url httpConfig: - followRedirects: true` + followRedirects: true + slackConfigs: + - apiURL: + key: api-url + name: "s-receiver-api-url" + actions: + - type: type + text: text + name: my-action + confirm: + text: text + fields: + - title: title + value: value` amConfCrd1_mynamespace := fmt.Sprintf(amConfCrd1, "mynamespace", "") amConfCrd1_mynamespace_alloyLabel := fmt.Sprintf(amConfCrd1, "mynamespace", `{alloy: "yes"}`) @@ -160,6 +175,17 @@ receivers: - name: "null" - name: mynamespace/alertmgr-config1/null - name: mynamespace/alertmgr-config1/myamc + slack_configs: + - api_url: https://val1.com + fields: + - title: title + value: value + actions: + - type: type + text: text + name: my-action + confirm: + text: text webhook_configs: - http_config: follow_redirects: true @@ -196,6 +222,17 @@ receivers: - name: "null" - name: mynamespace/alertmgr-config1/null - name: mynamespace/alertmgr-config1/myamc + slack_configs: + - api_url: https://val1.com + fields: + - title: title + value: value + actions: + - type: type + text: text + name: my-action + confirm: + text: text webhook_configs: - http_config: follow_redirects: true @@ -349,6 +386,19 @@ spec: testLogger = util.TestLogger(t) } + c := fake.NewSimpleClientset( + &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "s-receiver-api-url", + Namespace: "mynamespace", + }, + Data: map[string][]byte{ + "api-url": []byte("https://val1.com"), + }, + }, + ) + store := assets.NewStoreBuilder(c.CoreV1(), c.CoreV1()) + processor := &eventProcessor{ queue: workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[kubernetes.Event]()), stopChan: make(chan struct{}), @@ -361,6 +411,7 @@ spec: cfgSelector: cfgSelector, metrics: newMetrics(), logger: testLogger, + storeBuilder: store, } ctx := t.Context()