mirror of
https://github.com/coreos/prometheus-operator.git
synced 2026-02-05 06:45:27 +01:00
feat: allow UTF-8 characters in label names
Follow-up from #7637 to complete the UTF8 support for labels Related-to: #7362 Assisted-by: Cursor Signed-off-by: Jayapriya Pai <slashpai9@gmail.com>
This commit is contained in:
@@ -321,6 +321,7 @@ func testAllNSPrometheus(t *testing.T) {
|
||||
"PrometheusAgentSSetServiceName": testPrometheusAgentSSetServiceName,
|
||||
"PrometheusReconciliationOnSecretChanges": testPrometheusReconciliationOnSecretChanges,
|
||||
"PrometheusUTF8MetricsSupport": testPrometheusUTF8MetricsSupport,
|
||||
"PrometheusUTF8LabelSupport": testPrometheusUTF8LabelSupport,
|
||||
}
|
||||
|
||||
for name, f := range testFuncs {
|
||||
|
||||
@@ -4930,22 +4930,15 @@ func testRelabelConfigCRDValidation(t *testing.T) {
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
scenario: "empty-source-lbl",
|
||||
scenario: "accepts-utf-8-labels",
|
||||
relabelConfigs: []monitoringv1.RelabelConfig{
|
||||
{
|
||||
SourceLabels: []monitoringv1.LabelName{""},
|
||||
SourceLabels: []monitoringv1.LabelName{"app.info"},
|
||||
Action: "replace",
|
||||
TargetLabel: "app.info",
|
||||
Replacement: ptr.To("test.app"),
|
||||
},
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
scenario: "invalid-source-lbl",
|
||||
relabelConfigs: []monitoringv1.RelabelConfig{
|
||||
{
|
||||
SourceLabels: []monitoringv1.LabelName{"metric%)"},
|
||||
},
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -5501,6 +5494,7 @@ func testPrometheusUTF8MetricsSupport(t *testing.T) {
|
||||
testCtx := framework.NewTestCtx(t)
|
||||
defer testCtx.Cleanup(t)
|
||||
ns := framework.CreateNamespace(context.Background(), t, testCtx)
|
||||
|
||||
// Disable admission webhook for rule since utf8 is not enabled by default and rule contain metric name with utf8 characters.
|
||||
ruleNamespaceSelector := map[string]string{"excludeFromWebhook": "true"}
|
||||
err := framework.AddLabelsToNamespace(context.Background(), ns, ruleNamespaceSelector)
|
||||
@@ -5720,6 +5714,153 @@ func testPrometheusUTF8MetricsSupport(t *testing.T) {
|
||||
require.NoError(t, err, "UTF-8 alert rule should be queryable")
|
||||
}
|
||||
|
||||
func testPrometheusUTF8LabelSupport(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCtx := framework.NewTestCtx(t)
|
||||
defer testCtx.Cleanup(t)
|
||||
ns := framework.CreateNamespace(context.Background(), t, testCtx)
|
||||
|
||||
framework.SetupPrometheusRBAC(context.Background(), t, testCtx, ns)
|
||||
|
||||
name := "prometheus-utf8-test"
|
||||
|
||||
// Create deployment for instrumented sample app
|
||||
deployment := &appsv1.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "instrumented-sample-app",
|
||||
Namespace: ns,
|
||||
Labels: map[string]string{
|
||||
"app": "instrumented-sample-app",
|
||||
},
|
||||
},
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: ptr.To(int32(1)),
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{"app.name": "instrumented-sample-app"},
|
||||
},
|
||||
Template: v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"app.name": "instrumented-sample-app",
|
||||
},
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{{
|
||||
Name: "instrumented-sample-app",
|
||||
Image: "quay.io/prometheus-operator/instrumented-sample-app:latest",
|
||||
Ports: []v1.ContainerPort{{
|
||||
Name: "web",
|
||||
ContainerPort: 8080,
|
||||
Protocol: v1.ProtocolTCP,
|
||||
}},
|
||||
}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
_, err := framework.KubeClient.AppsV1().Deployments(ns).Create(context.Background(), deployment, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
service := &v1.Service{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "utf8-test-service",
|
||||
Namespace: ns,
|
||||
Labels: map[string]string{
|
||||
"app.name": "instrumented-sample-app",
|
||||
"group": "test.app",
|
||||
"cluster": "dev",
|
||||
},
|
||||
},
|
||||
Spec: v1.ServiceSpec{
|
||||
Ports: []v1.ServicePort{{Name: "web", Port: 8080, TargetPort: intstr.FromInt(8080)}},
|
||||
Selector: map[string]string{"app.name": "instrumented-sample-app"},
|
||||
},
|
||||
}
|
||||
_, err = framework.KubeClient.CoreV1().Services(ns).Create(context.Background(), service, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
sm := &monitoringv1.ServiceMonitor{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "utf8-servicemonitor",
|
||||
Namespace: ns,
|
||||
Labels: map[string]string{"group": "test.app", "app.name": "instrumented-sample-app"},
|
||||
},
|
||||
Spec: monitoringv1.ServiceMonitorSpec{
|
||||
Selector: metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{"app.name": "instrumented-sample-app"},
|
||||
},
|
||||
Endpoints: []monitoringv1.Endpoint{{
|
||||
Port: "web",
|
||||
Interval: "2s",
|
||||
RelabelConfigs: []monitoringv1.RelabelConfig{{
|
||||
SourceLabels: []monitoringv1.LabelName{"__meta_kubernetes_service_label_cluster"},
|
||||
TargetLabel: "service_clustér_label",
|
||||
Action: "replace",
|
||||
}},
|
||||
BasicAuth: &monitoringv1.BasicAuth{
|
||||
Username: v1.SecretKeySelector{
|
||||
LocalObjectReference: v1.LocalObjectReference{Name: "basic-auth"},
|
||||
Key: "username",
|
||||
},
|
||||
Password: v1.SecretKeySelector{
|
||||
LocalObjectReference: v1.LocalObjectReference{Name: "basic-auth"},
|
||||
Key: "password",
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
secret := &v1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "basic-auth",
|
||||
Namespace: ns,
|
||||
},
|
||||
Type: v1.SecretTypeOpaque,
|
||||
StringData: map[string]string{
|
||||
"username": "user",
|
||||
"password": "pass",
|
||||
},
|
||||
}
|
||||
_, err = framework.KubeClient.CoreV1().Secrets(ns).Create(context.Background(), secret, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = framework.MonClientV1.ServiceMonitors(ns).Create(context.Background(), sm, metav1.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = framework.WaitForDeploymentReady(context.Background(), ns, "instrumented-sample-app", 1)
|
||||
require.NoError(t, err)
|
||||
|
||||
prom := framework.MakeBasicPrometheus(ns, name, "test.app", 1)
|
||||
_, err = framework.CreatePrometheusAndWaitUntilReady(context.Background(), ns, prom)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Default Prometheus service name is "prometheus-operated".
|
||||
promSvcName := "prometheus-operated"
|
||||
|
||||
// Wait for the instrumented-sample-app target to be discovered
|
||||
err = framework.WaitForHealthyTargets(context.Background(), ns, promSvcName, 1)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify UTF8 labels work in queries.
|
||||
err = wait.PollUntilContextTimeout(context.Background(), 5*time.Second, 2*time.Minute, false, func(ctx context.Context) (bool, error) {
|
||||
results, err := framework.PrometheusQuery(ns, promSvcName, "http", `{"service_clustér_label"="dev"}`)
|
||||
if err != nil {
|
||||
t.Logf("UTF8 label query failed: %v", err)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if len(results) == 0 {
|
||||
t.Logf("UTF8 label query returned no results")
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
})
|
||||
require.NoError(t, err, "UTF-8 label queries should work in Prometheus 3.0+ queries")
|
||||
}
|
||||
|
||||
func isAlertmanagerDiscoveryWorking(ns, promSVCName, alertmanagerName string) func(ctx context.Context) (bool, error) {
|
||||
return func(ctx context.Context) (bool, error) {
|
||||
pods, err := framework.KubeClient.CoreV1().Pods(ns).List(
|
||||
|
||||
Reference in New Issue
Block a user