diff --git a/bundle/manifests/monitoring.rhobs_monitoringstacks.yaml b/bundle/manifests/monitoring.rhobs_monitoringstacks.yaml
index 3eb499399..67d956d8c 100644
--- a/bundle/manifests/monitoring.rhobs_monitoringstacks.yaml
+++ b/bundle/manifests/monitoring.rhobs_monitoringstacks.yaml
@@ -50,6 +50,21 @@ spec:
default: false
description: Disables the deployment of Alertmanager.
type: boolean
+ matcherStrategy:
+ default: None
+ description: |-
+ Define how AlertmanagerConfig objects process incoming alerts.
+ With OnNamespace, routes only match alerts with a namespace label
+ equal to the namespace of the AlertmanagerConfig.
+ With OnNamespaceExceptForAlertmanagerNamespace, routes behave like
+ OnNamespace but AlertmanagerConfig resources in the Alertmanager's
+ own namespace match all alerts.
+ With None, routes match all incoming alerts regardless of namespace.
+ enum:
+ - OnNamespace
+ - OnNamespaceExceptForAlertmanagerNamespace
+ - None
+ type: string
replicas:
default: 2
description: Number of replicas/pods to deploy for Alertmanager.
diff --git a/bundle/manifests/observability-operator.clusterserviceversion.yaml b/bundle/manifests/observability-operator.clusterserviceversion.yaml
index cd6831d02..a843a1f31 100644
--- a/bundle/manifests/observability-operator.clusterserviceversion.yaml
+++ b/bundle/manifests/observability-operator.clusterserviceversion.yaml
@@ -43,7 +43,7 @@ metadata:
certified: "false"
console.openshift.io/operator-monitoring-default: "true"
containerImage: observability-operator:1.3.0
- createdAt: "2026-05-18T17:17:51Z"
+ createdAt: "2026-05-19T06:53:02Z"
description: A Go based Kubernetes operator to setup and manage highly available
Monitoring Stack using Prometheus, Alertmanager and Thanos Querier.
operatorframework.io/cluster-monitoring: "true"
diff --git a/deploy/crds/common/monitoring.rhobs_monitoringstacks.yaml b/deploy/crds/common/monitoring.rhobs_monitoringstacks.yaml
index e4fd8f377..376c6b876 100644
--- a/deploy/crds/common/monitoring.rhobs_monitoringstacks.yaml
+++ b/deploy/crds/common/monitoring.rhobs_monitoringstacks.yaml
@@ -50,6 +50,21 @@ spec:
default: false
description: Disables the deployment of Alertmanager.
type: boolean
+ matcherStrategy:
+ default: None
+ description: |-
+ Define how AlertmanagerConfig objects process incoming alerts.
+ With OnNamespace, routes only match alerts with a namespace label
+ equal to the namespace of the AlertmanagerConfig.
+ With OnNamespaceExceptForAlertmanagerNamespace, routes behave like
+ OnNamespace but AlertmanagerConfig resources in the Alertmanager's
+ own namespace match all alerts.
+ With None, routes match all incoming alerts regardless of namespace.
+ enum:
+ - OnNamespace
+ - OnNamespaceExceptForAlertmanagerNamespace
+ - None
+ type: string
replicas:
default: 2
description: Number of replicas/pods to deploy for Alertmanager.
diff --git a/docs/api.md b/docs/api.md
index 550f99792..1dbd2ce6b 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -230,6 +230,22 @@ Define Alertmanager config
Default: false
false |
+
+ | matcherStrategy |
+ enum |
+
+ Define how AlertmanagerConfig objects process incoming alerts.
+With OnNamespace, routes only match alerts with a namespace label
+equal to the namespace of the AlertmanagerConfig.
+With OnNamespaceExceptForAlertmanagerNamespace, routes behave like
+OnNamespace but AlertmanagerConfig resources in the Alertmanager's
+own namespace match all alerts.
+With None, routes match all incoming alerts regardless of namespace.
+
+ Enum: OnNamespace, OnNamespaceExceptForAlertmanagerNamespace, None
+ Default: None
+ |
+ false |
| replicas |
integer |
diff --git a/pkg/apis/monitoring/v1alpha1/types.go b/pkg/apis/monitoring/v1alpha1/types.go
index 02c64de88..9918ea809 100644
--- a/pkg/apis/monitoring/v1alpha1/types.go
+++ b/pkg/apis/monitoring/v1alpha1/types.go
@@ -55,6 +55,9 @@ const (
// +kubebuilder:validation:Enum=CreateClusterRoleBindings;NoClusterRoleBindings
type ClusterRoleBindingPolicy string
+// +kubebuilder:validation:Enum=OnNamespace;OnNamespaceExceptForAlertmanagerNamespace;None
+type AlertmanagerConfigMatcherStrategyType string
+
const (
// CreateClusterRoleBindings instructs the MonitoringStack to create the
// default ClusterRoleBindings if a NamespaceSelector is present. Note that
@@ -69,6 +72,22 @@ const (
NoClusterRoleBindings ClusterRoleBindingPolicy = "NoClusterRoleBindings"
)
+const (
+ // OnNamespaceMatcherStrategy configures AlertmanagerConfig routes to only
+ // match alerts with a namespace label equal to the namespace of the
+ // AlertmanagerConfig resource.
+ OnNamespaceMatcherStrategy AlertmanagerConfigMatcherStrategyType = "OnNamespace"
+
+ // OnNamespaceExceptForAlertmanagerNamespaceMatcherStrategy behaves like
+ // OnNamespace, but AlertmanagerConfig resources in the same namespace as
+ // the Alertmanager instance match all alerts regardless of namespace.
+ OnNamespaceExceptForAlertmanagerNamespaceMatcherStrategy AlertmanagerConfigMatcherStrategyType = "OnNamespaceExceptForAlertmanagerNamespace"
+
+ // NoneMatcherStrategy configures AlertmanagerConfig routes to match all
+ // incoming alerts regardless of namespace.
+ NoneMatcherStrategy AlertmanagerConfigMatcherStrategyType = "None"
+)
+
// MonitoringStackSpec is the specification for desired Monitoring Stack
type MonitoringStackSpec struct {
// +optional
@@ -264,6 +283,17 @@ type AlertmanagerConfig struct {
// +kubebuilder:validation:Minimum=0
Replicas *int32 `json:"replicas,omitempty"`
+ // Define how AlertmanagerConfig objects process incoming alerts.
+ // With OnNamespace, routes only match alerts with a namespace label
+ // equal to the namespace of the AlertmanagerConfig.
+ // With OnNamespaceExceptForAlertmanagerNamespace, routes behave like
+ // OnNamespace but AlertmanagerConfig resources in the Alertmanager's
+ // own namespace match all alerts.
+ // With None, routes match all incoming alerts regardless of namespace.
+ // +optional
+ // +kubebuilder:default="None"
+ MatcherStrategy AlertmanagerConfigMatcherStrategyType `json:"matcherStrategy,omitempty"`
+
// Configure TLS options for the Alertmanager web server.
// +optional
WebTLSConfig *WebTLSConfig `json:"webTLSConfig,omitempty"`
diff --git a/pkg/controllers/monitoring/monitoring-stack/alertmanager.go b/pkg/controllers/monitoring/monitoring-stack/alertmanager.go
index 3f512e468..c849290b9 100644
--- a/pkg/controllers/monitoring/monitoring-stack/alertmanager.go
+++ b/pkg/controllers/monitoring/monitoring-stack/alertmanager.go
@@ -38,8 +38,11 @@ func newAlertmanager(
Replicas: ms.Spec.AlertmanagerConfig.Replicas,
ServiceAccountName: rbacResourceName,
AlertmanagerConfigSelector: resourceSelector,
- NodeSelector: ms.Spec.NodeSelector,
- Tolerations: ms.Spec.Tolerations,
+ AlertmanagerConfigMatcherStrategy: monv1.AlertmanagerConfigMatcherStrategy{
+ Type: monv1.AlertmanagerConfigMatcherStrategyType(ms.Spec.AlertmanagerConfig.MatcherStrategy),
+ },
+ NodeSelector: ms.Spec.NodeSelector,
+ Tolerations: ms.Spec.Tolerations,
Affinity: &corev1.Affinity{
PodAntiAffinity: &corev1.PodAntiAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
diff --git a/pkg/controllers/monitoring/monitoring-stack/alertmanager_test.go b/pkg/controllers/monitoring/monitoring-stack/alertmanager_test.go
new file mode 100644
index 000000000..36f9304da
--- /dev/null
+++ b/pkg/controllers/monitoring/monitoring-stack/alertmanager_test.go
@@ -0,0 +1,52 @@
+package monitoringstack
+
+import (
+ "testing"
+
+ monv1 "github.com/rhobs/obo-prometheus-operator/pkg/apis/monitoring/v1"
+ "gotest.tools/v3/assert"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+ stack "github.com/rhobs/observability-operator/pkg/apis/monitoring/v1alpha1"
+)
+
+func TestNewAlertmanagerMatcherStrategy(t *testing.T) {
+ for _, tc := range []struct {
+ name string
+ strategy stack.AlertmanagerConfigMatcherStrategyType
+ expected monv1.AlertmanagerConfigMatcherStrategyType
+ }{
+ {
+ name: "None",
+ strategy: stack.NoneMatcherStrategy,
+ expected: monv1.NoneConfigMatcherStrategyType,
+ },
+ {
+ name: "OnNamespace",
+ strategy: stack.OnNamespaceMatcherStrategy,
+ expected: monv1.OnNamespaceConfigMatcherStrategyType,
+ },
+ {
+ name: "OnNamespaceExceptForAlertmanagerNamespace",
+ strategy: stack.OnNamespaceExceptForAlertmanagerNamespaceMatcherStrategy,
+ expected: monv1.OnNamespaceExceptForAlertmanagerNamespaceConfigMatcherStrategyType,
+ },
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ ms := &stack.MonitoringStack{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: "test",
+ Namespace: "test-ns",
+ },
+ Spec: stack.MonitoringStackSpec{
+ AlertmanagerConfig: stack.AlertmanagerConfig{
+ MatcherStrategy: tc.strategy,
+ },
+ },
+ }
+
+ am := newAlertmanager(ms, "test-sa", AlertmanagerConfiguration{})
+ assert.Equal(t, am.Spec.AlertmanagerConfigMatcherStrategy.Type, tc.expected)
+ })
+ }
+}