mirror of
https://github.com/coreos/prometheus-operator.git
synced 2026-02-05 15:46:31 +01:00
chore: add well-known labels to statefulsets
Signed-off-by: Simon Pasquier <spasquie@redhat.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
## Unreleased
|
||||
|
||||
* [CHANGE/BUGFIX] Add the `--watch-referenced-objects-in-all-namespaces` CLI argument. When enabled, the operator watches for secrets and configmaps in both workload and configuration resources. It ensures that reconciliation happens when a referenced secret/configmap is updated. #7615
|
||||
* [ENHANCEMENT] Add well-known Kubernetes labels to workload objects managed by the operator (StatefulSet and DaemonSet). #7786
|
||||
|
||||
## 0.84.0 / 2025-07-14
|
||||
|
||||
|
||||
@@ -275,6 +275,16 @@ func (c *Operator) bootstrap(ctx context.Context, config operator.Config) error
|
||||
c.kclient,
|
||||
resyncPeriod,
|
||||
func(options *metav1.ListOptions) {
|
||||
// TODO(simonpasquier): use a more restrictive label selector
|
||||
// selecting only Alertmanager statefulsets (e.g.
|
||||
// "app.kubernetes.io/name in (alertmanager)").
|
||||
//
|
||||
// We need to wait for a couple of releases after [1] merges to
|
||||
// ensure that the expected labels have been propagated to the
|
||||
// Alertmanager statefulsets otherwise the informer won't
|
||||
// select any object.
|
||||
//
|
||||
// [1] https://github.com/prometheus-operator/prometheus-operator/pull/7786
|
||||
options.LabelSelector = operator.ManagedByOperatorLabelSelector()
|
||||
},
|
||||
),
|
||||
|
||||
@@ -110,10 +110,11 @@ func makeStatefulSet(logger *slog.Logger, am *monitoringv1.Alertmanager, config
|
||||
operator.UpdateObject(
|
||||
statefulset,
|
||||
operator.WithName(prefixedName(am.Name)),
|
||||
operator.WithInputHashAnnotation(inputHash),
|
||||
operator.WithAnnotations(am.GetAnnotations()),
|
||||
operator.WithAnnotations(config.Annotations),
|
||||
operator.WithInputHashAnnotation(inputHash),
|
||||
operator.WithLabels(am.GetLabels()),
|
||||
operator.WithSelectorLabels(spec.Selector),
|
||||
operator.WithLabels(config.Labels),
|
||||
operator.WithManagingOwner(am),
|
||||
operator.WithoutKubectlAnnotations(),
|
||||
|
||||
@@ -54,29 +54,35 @@ func TestStatefulSetLabelingAndAnnotations(t *testing.T) {
|
||||
// kubectl annotations must not be on the statefulset so kubectl does
|
||||
// not manage the generated object
|
||||
expectedStatefulSetAnnotations := map[string]string{
|
||||
"prometheus-operator-input-hash": "",
|
||||
"prometheus-operator-input-hash": "abc",
|
||||
"testannotation": "testannotationvalue",
|
||||
}
|
||||
|
||||
expectedStatefulSetLabels := map[string]string{
|
||||
"testlabel": "testlabelvalue",
|
||||
"managed-by": "prometheus-operator",
|
||||
"testlabel": "testlabelvalue",
|
||||
"managed-by": "prometheus-operator",
|
||||
"alertmanager": "test",
|
||||
"app.kubernetes.io/instance": "test",
|
||||
"app.kubernetes.io/managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/name": "alertmanager",
|
||||
}
|
||||
|
||||
expectedPodLabels := map[string]string{
|
||||
"alertmanager": "",
|
||||
"alertmanager": "test",
|
||||
"app.kubernetes.io/name": "alertmanager",
|
||||
"app.kubernetes.io/version": strings.TrimPrefix(operator.DefaultAlertmanagerVersion, "v"),
|
||||
"app.kubernetes.io/managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/instance": "",
|
||||
"app.kubernetes.io/instance": "test",
|
||||
}
|
||||
|
||||
sset, err := makeStatefulSet(nil, &monitoringv1.Alertmanager{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "ns",
|
||||
Labels: labels,
|
||||
Annotations: annotations,
|
||||
},
|
||||
}, defaultTestConfig, "", &operator.ShardedSecret{})
|
||||
}, defaultTestConfig, "abc", &operator.ShardedSecret{})
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -105,6 +105,23 @@ func WithLabels(labels map[string]string) ObjectOption {
|
||||
}
|
||||
}
|
||||
|
||||
// WithSelectorLabels merges the labels from the selector with the existing
|
||||
// object's labels.
|
||||
// The selector's labels take precedence over the existing ones.
|
||||
func WithSelectorLabels(selector *metav1.LabelSelector) ObjectOption {
|
||||
return func(o metav1.Object) {
|
||||
if selector == nil {
|
||||
return
|
||||
}
|
||||
|
||||
l := Map{}
|
||||
l = l.Merge(selector.MatchLabels)
|
||||
l = l.Merge(o.GetLabels())
|
||||
|
||||
o.SetLabels(l)
|
||||
}
|
||||
}
|
||||
|
||||
// WithAnnotations merges the given annotations with the existing object's annotations.
|
||||
// The given annotations take precedence over the existing ones.
|
||||
func WithAnnotations(annotations map[string]string) ObjectOption {
|
||||
|
||||
@@ -58,9 +58,9 @@ func makeDaemonSet(
|
||||
operator.WithAnnotations(config.Annotations),
|
||||
operator.WithLabels(objMeta.GetLabels()),
|
||||
operator.WithLabels(map[string]string{
|
||||
prompkg.PrometheusNameLabelName: objMeta.GetName(),
|
||||
prompkg.PrometheusModeLabelName: prometheusMode,
|
||||
}),
|
||||
operator.WithSelectorLabels(spec.Selector),
|
||||
operator.WithLabels(config.Labels),
|
||||
operator.WithManagingOwner(p),
|
||||
operator.WithoutKubectlAnnotations(),
|
||||
|
||||
@@ -156,22 +156,27 @@ func TestDaemonSetLabelingAndAnnotations(t *testing.T) {
|
||||
}
|
||||
|
||||
expectedDaemonSetLabels := map[string]string{
|
||||
"testlabel": "testlabelvalue",
|
||||
"operator.prometheus.io/name": "",
|
||||
"operator.prometheus.io/mode": "agent",
|
||||
"managed-by": "prometheus-operator",
|
||||
"testlabel": "testlabelvalue",
|
||||
"operator.prometheus.io/name": "test",
|
||||
"operator.prometheus.io/mode": "agent",
|
||||
"managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/instance": "test",
|
||||
"app.kubernetes.io/managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/name": "prometheus-agent",
|
||||
}
|
||||
|
||||
expectedPodLabels := map[string]string{
|
||||
"app.kubernetes.io/name": "prometheus-agent",
|
||||
"app.kubernetes.io/version": strings.TrimPrefix(operator.DefaultPrometheusVersion, "v"),
|
||||
"app.kubernetes.io/managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/instance": "",
|
||||
"operator.prometheus.io/name": "",
|
||||
"app.kubernetes.io/instance": "test",
|
||||
"operator.prometheus.io/name": "test",
|
||||
}
|
||||
|
||||
dset, err := makeDaemonSetFromPrometheus(monitoringv1alpha1.PrometheusAgent{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "ns",
|
||||
Labels: labels,
|
||||
Annotations: annotations,
|
||||
},
|
||||
|
||||
@@ -65,15 +65,14 @@ func makeStatefulSet(
|
||||
operator.UpdateObject(
|
||||
statefulset,
|
||||
operator.WithName(name),
|
||||
operator.WithInputHashAnnotation(inputHash),
|
||||
operator.WithAnnotations(objMeta.GetAnnotations()),
|
||||
operator.WithAnnotations(config.Annotations),
|
||||
operator.WithInputHashAnnotation(inputHash),
|
||||
operator.WithLabels(objMeta.GetLabels()),
|
||||
operator.WithLabels(map[string]string{
|
||||
prompkg.ShardLabelName: fmt.Sprintf("%d", shard),
|
||||
prompkg.PrometheusNameLabelName: objMeta.GetName(),
|
||||
prompkg.PrometheusModeLabelName: prometheusMode,
|
||||
}),
|
||||
operator.WithSelectorLabels(spec.Selector),
|
||||
operator.WithLabels(config.Labels),
|
||||
operator.WithManagingOwner(p),
|
||||
operator.WithoutKubectlAnnotations(),
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package prometheusagent
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -147,7 +148,7 @@ func makeStatefulSetFromPrometheus(p monitoringv1alpha1.PrometheusAgent) (*appsv
|
||||
&p,
|
||||
defaultTestConfig,
|
||||
cg,
|
||||
"",
|
||||
"abc",
|
||||
0,
|
||||
&operator.ShardedSecret{})
|
||||
}
|
||||
@@ -333,6 +334,58 @@ func TestScrapeFailureLogFileVolumeMountNotPresent(t *testing.T) {
|
||||
require.False(t, found, "Scrape failure log file mounted, when it shouldn't be.")
|
||||
}
|
||||
|
||||
func TestStatefulSetLabelingAndAnnotations(t *testing.T) {
|
||||
labels := map[string]string{
|
||||
"testlabel": "testlabelvalue",
|
||||
}
|
||||
annotations := map[string]string{
|
||||
"testannotation": "testannotationvalue",
|
||||
"kubectl.kubernetes.io/last-applied-configuration": "something",
|
||||
"kubectl.kubernetes.io/something": "something",
|
||||
}
|
||||
|
||||
// kubectl annotations must not be on the statefulset so kubectl does
|
||||
// not manage the generated object
|
||||
expectedStatefulSetAnnotations := map[string]string{
|
||||
"prometheus-operator-input-hash": "abc",
|
||||
"testannotation": "testannotationvalue",
|
||||
}
|
||||
|
||||
expectedStatefulSetLabels := map[string]string{
|
||||
"testlabel": "testlabelvalue",
|
||||
"operator.prometheus.io/name": "test",
|
||||
"operator.prometheus.io/shard": "0",
|
||||
"operator.prometheus.io/mode": "agent",
|
||||
"managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/instance": "test",
|
||||
"app.kubernetes.io/managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/name": "prometheus-agent",
|
||||
}
|
||||
|
||||
expectedPodLabels := map[string]string{
|
||||
"app.kubernetes.io/name": "prometheus-agent",
|
||||
"app.kubernetes.io/version": strings.TrimPrefix(operator.DefaultPrometheusVersion, "v"),
|
||||
"app.kubernetes.io/managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/instance": "test",
|
||||
"operator.prometheus.io/name": "test",
|
||||
"operator.prometheus.io/shard": "0",
|
||||
}
|
||||
|
||||
sset, err := makeStatefulSetFromPrometheus(monitoringv1alpha1.PrometheusAgent{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "ns",
|
||||
Labels: labels,
|
||||
Annotations: annotations,
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, expectedStatefulSetLabels, sset.Labels)
|
||||
require.Equal(t, expectedStatefulSetAnnotations, sset.Annotations)
|
||||
require.Equal(t, expectedPodLabels, sset.Spec.Template.ObjectMeta.Labels)
|
||||
}
|
||||
|
||||
func TestStatefulSetenableServiceLinks(t *testing.T) {
|
||||
tests := []struct {
|
||||
enableServiceLinks *bool
|
||||
|
||||
@@ -70,15 +70,14 @@ func makeStatefulSet(
|
||||
operator.UpdateObject(
|
||||
statefulset,
|
||||
operator.WithName(name),
|
||||
operator.WithInputHashAnnotation(inputHash),
|
||||
operator.WithAnnotations(objMeta.GetAnnotations()),
|
||||
operator.WithAnnotations(config.Annotations),
|
||||
operator.WithInputHashAnnotation(inputHash),
|
||||
operator.WithLabels(objMeta.GetLabels()),
|
||||
operator.WithLabels(map[string]string{
|
||||
prompkg.ShardLabelName: fmt.Sprintf("%d", shard),
|
||||
prompkg.PrometheusNameLabelName: objMeta.GetName(),
|
||||
prompkg.PrometheusModeLabelName: prometheusMode,
|
||||
}),
|
||||
operator.WithSelectorLabels(spec.Selector),
|
||||
operator.WithLabels(config.Labels),
|
||||
operator.WithManagingOwner(p),
|
||||
operator.WithoutKubectlAnnotations(),
|
||||
|
||||
@@ -59,7 +59,7 @@ func makeStatefulSetFromPrometheus(p monitoringv1.Prometheus) (*appsv1.StatefulS
|
||||
defaultTestConfig,
|
||||
cg,
|
||||
nil,
|
||||
"",
|
||||
"abc",
|
||||
0,
|
||||
&operator.ShardedSecret{})
|
||||
}
|
||||
@@ -73,33 +73,40 @@ func TestStatefulSetLabelingAndAnnotations(t *testing.T) {
|
||||
"kubectl.kubernetes.io/last-applied-configuration": "something",
|
||||
"kubectl.kubernetes.io/something": "something",
|
||||
}
|
||||
|
||||
// kubectl annotations must not be on the statefulset so kubectl does
|
||||
// not manage the generated object
|
||||
expectedStatefulSetAnnotations := map[string]string{
|
||||
"prometheus-operator-input-hash": "",
|
||||
"prometheus-operator-input-hash": "abc",
|
||||
"testannotation": "testannotationvalue",
|
||||
}
|
||||
|
||||
expectedStatefulSetLabels := map[string]string{
|
||||
"testlabel": "testlabelvalue",
|
||||
"operator.prometheus.io/name": "",
|
||||
"operator.prometheus.io/name": "test",
|
||||
"operator.prometheus.io/shard": "0",
|
||||
"operator.prometheus.io/mode": "server",
|
||||
"managed-by": "prometheus-operator",
|
||||
"prometheus": "test",
|
||||
"app.kubernetes.io/instance": "test",
|
||||
"app.kubernetes.io/managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/name": "prometheus",
|
||||
}
|
||||
|
||||
expectedPodLabels := map[string]string{
|
||||
"prometheus": "",
|
||||
"prometheus": "test",
|
||||
"app.kubernetes.io/name": "prometheus",
|
||||
"app.kubernetes.io/version": strings.TrimPrefix(operator.DefaultPrometheusVersion, "v"),
|
||||
"app.kubernetes.io/managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/instance": "",
|
||||
"operator.prometheus.io/name": "",
|
||||
"app.kubernetes.io/instance": "test",
|
||||
"operator.prometheus.io/name": "test",
|
||||
"operator.prometheus.io/shard": "0",
|
||||
}
|
||||
|
||||
sset, err := makeStatefulSetFromPrometheus(monitoringv1.Prometheus{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "ns",
|
||||
Labels: labels,
|
||||
Annotations: annotations,
|
||||
},
|
||||
|
||||
@@ -227,6 +227,16 @@ func New(ctx context.Context, restConfig *rest.Config, c operator.Config, logger
|
||||
o.kclient,
|
||||
resyncPeriod,
|
||||
func(options *metav1.ListOptions) {
|
||||
// TODO(simonpasquier): use a more restrictive label selector
|
||||
// selecting only ThanosRuler statefulsets (e.g.
|
||||
// "app.kubernetes.io/name in (thanos-ruler)").
|
||||
//
|
||||
// We need to wait for a couple of releases after [1] to ensure
|
||||
// that the expected labels have been propagated to the
|
||||
// ThanosRuler statefulsets otherwise the informer won't select
|
||||
// any object.
|
||||
//
|
||||
// [1] https://github.com/prometheus-operator/prometheus-operator/pull/7786
|
||||
options.LabelSelector = operator.ManagedByOperatorLabelSelector()
|
||||
},
|
||||
),
|
||||
|
||||
@@ -75,10 +75,11 @@ func makeStatefulSet(tr *monitoringv1.ThanosRuler, config Config, ruleConfigMapN
|
||||
operator.UpdateObject(
|
||||
statefulset,
|
||||
operator.WithName(prefixedName(tr.Name)),
|
||||
operator.WithInputHashAnnotation(inputHash),
|
||||
operator.WithAnnotations(tr.GetAnnotations()),
|
||||
operator.WithAnnotations(config.Annotations),
|
||||
operator.WithInputHashAnnotation(inputHash),
|
||||
operator.WithLabels(tr.GetLabels()),
|
||||
operator.WithSelectorLabels(spec.Selector),
|
||||
operator.WithLabels(config.Labels),
|
||||
operator.WithManagingOwner(tr),
|
||||
operator.WithoutKubectlAnnotations(),
|
||||
|
||||
@@ -44,28 +44,36 @@ var (
|
||||
|
||||
func TestStatefulSetLabelingAndAnnotations(t *testing.T) {
|
||||
labels := map[string]string{
|
||||
"testlabel": "testlabelvalue",
|
||||
"managed-by": "prometheus-operator",
|
||||
"testlabel": "testlabelvalue",
|
||||
"managed-by": "prometheus-operator",
|
||||
"thanos-ruler": "test",
|
||||
"app.kubernetes.io/instance": "test",
|
||||
"app.kubernetes.io/managed-by": "prometheus-operator",
|
||||
"app.kubernetes.io/name": "thanos-ruler",
|
||||
}
|
||||
|
||||
annotations := map[string]string{
|
||||
"testannotation": "testannotationvalue",
|
||||
"kubectl.kubernetes.io/last-applied-configuration": "something",
|
||||
"kubectl.kubernetes.io/something": "something",
|
||||
}
|
||||
|
||||
// kubectl annotations must not be on the statefulset so kubectl does
|
||||
// not manage the generated object
|
||||
expectedAnnotations := map[string]string{
|
||||
"prometheus-operator-input-hash": "",
|
||||
"prometheus-operator-input-hash": "abc",
|
||||
"testannotation": "testannotationvalue",
|
||||
}
|
||||
|
||||
sset, err := makeStatefulSet(&monitoringv1.ThanosRuler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test",
|
||||
Namespace: "ns",
|
||||
Labels: labels,
|
||||
Annotations: annotations,
|
||||
},
|
||||
Spec: monitoringv1.ThanosRulerSpec{QueryEndpoints: emptyQueryEndpoints},
|
||||
}, defaultTestConfig, nil, "", &operator.ShardedSecret{})
|
||||
}, defaultTestConfig, nil, "abc", &operator.ShardedSecret{})
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user