Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package golang-github-prometheus-prometheus 
for openSUSE:Factory checked in at 2026-04-23 17:03:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/golang-github-prometheus-prometheus (Old)
 and      
/work/SRC/openSUSE:Factory/.golang-github-prometheus-prometheus.new.11940 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "golang-github-prometheus-prometheus"

Thu Apr 23 17:03:14 2026 rev:70 rq:1348534 version:3.11.2

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/golang-github-prometheus-prometheus/golang-github-prometheus-prometheus.changes
  2026-04-18 21:30:28.371172299 +0200
+++ 
/work/SRC/openSUSE:Factory/.golang-github-prometheus-prometheus.new.11940/golang-github-prometheus-prometheus.changes
       2026-04-23 17:03:23.473728214 +0200
@@ -1,0 +2,15 @@
+Sat Apr 18 05:42:24 UTC 2026 - Johannes Kastl 
<[email protected]>
+
+- update to 3.11.2:
+  This release has a fix for a Stored XSS vulnerability that can be
+  triggered via crafted metric names and label values in Prometheus
+  web UI tooltips and metrics explorer. Thanks to Duc Anh Nguyen
+  from TinyxLab for reporting it.
+  * [SECURITY] UI: Fix stored XSS via unescaped metric names and
+    labels. CVE-2026-40179. #18506
+  * [ENHANCEMENT] Consul SD: Introduce health_filter field for
+    Health API filtering. #18499
+  * [BUGFIX] Consul SD: Fix filter parameter being incorrectly
+    applied to the Health API. #18499
+
+-------------------------------------------------------------------

Old:
----
  prometheus-3.11.1.obscpio

New:
----
  prometheus-3.11.2.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ golang-github-prometheus-prometheus.spec ++++++
--- /var/tmp/diff_new_pack.rFgTBP/_old  2026-04-23 17:03:53.882980985 +0200
+++ /var/tmp/diff_new_pack.rFgTBP/_new  2026-04-23 17:03:53.882980985 +0200
@@ -27,7 +27,7 @@
 %endif
 
 Name:           golang-github-prometheus-prometheus
-Version:        3.11.1
+Version:        3.11.2
 Release:        0
 Summary:        The Prometheus monitoring system and time series database
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.rFgTBP/_old  2026-04-23 17:03:53.994985600 +0200
+++ /var/tmp/diff_new_pack.rFgTBP/_new  2026-04-23 17:03:53.998985765 +0200
@@ -6,7 +6,7 @@
     <param name="exclude">go.work</param>
     <param name="exclude">go.work.sum</param>
     <param name="versionformat">@PARENT_TAG@</param>
-    <param name="revision">v3.11.1</param>
+    <param name="revision">v3.11.2</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="match-tag">v3*</param>
   </service>

++++++ node_modules.obscpio ++++++
/work/SRC/openSUSE:Factory/golang-github-prometheus-prometheus/node_modules.obscpio
 
/work/SRC/openSUSE:Factory/.golang-github-prometheus-prometheus.new.11940/node_modules.obscpio
 differ: char 2878347, line 11107

++++++ node_modules.spec.inc ++++++
++++ 1263 lines (skipped)
++++ between 
/work/SRC/openSUSE:Factory/golang-github-prometheus-prometheus/node_modules.spec.inc
++++ and 
/work/SRC/openSUSE:Factory/.golang-github-prometheus-prometheus.new.11940/node_modules.spec.inc

++++++ package-lock.json ++++++
++++ 625 lines (skipped)
++++ between 
/work/SRC/openSUSE:Factory/golang-github-prometheus-prometheus/package-lock.json
++++ and 
/work/SRC/openSUSE:Factory/.golang-github-prometheus-prometheus.new.11940/package-lock.json

++++++ prometheus-3.11.1.obscpio -> prometheus-3.11.2.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prometheus-3.11.1/CHANGELOG.md 
new/prometheus-3.11.2/CHANGELOG.md
--- old/prometheus-3.11.1/CHANGELOG.md  2026-04-07 16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/CHANGELOG.md  2026-04-13 13:39:08.000000000 +0200
@@ -1,5 +1,13 @@
 # Changelog
 
+## 3.11.2 / 2026-04-13
+
+This release has a fix for a Stored XSS vulnerability that can be triggered 
via crafted metric names and label values in Prometheus web UI tooltips and 
metrics explorer. Thanks to Duc Anh Nguyen from TinyxLab for reporting it.
+
+- [SECURITY] UI: Fix stored XSS via unescaped metric names and labels. 
CVE-2026-40179. #18506
+- [ENHANCEMENT] Consul SD: Introduce `health_filter` field for Health API 
filtering. #18499
+- [BUGFIX] Consul SD: Fix filter parameter being incorrectly applied to the 
Health API. #18499
+
 ## 3.11.1 / 2026-04-07
 
 - [BUGFIX] Tracing: Fix startup failure for OTLP HTTP tracing with `insecure: 
true`. #18469
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prometheus-3.11.1/VERSION 
new/prometheus-3.11.2/VERSION
--- old/prometheus-3.11.1/VERSION       2026-04-07 16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/VERSION       2026-04-13 13:39:08.000000000 +0200
@@ -1 +1 @@
-3.11.1
+3.11.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prometheus-3.11.1/config/config_test.go 
new/prometheus-3.11.2/config/config_test.go
--- old/prometheus-3.11.1/config/config_test.go 2026-04-07 16:55:05.000000000 
+0200
+++ new/prometheus-3.11.2/config/config_test.go 2026-04-13 13:39:08.000000000 
+0200
@@ -481,6 +481,7 @@
                                        PathPrefix:      "/consul",
                                        Token:           "mysecret",
                                        Services:        []string{"nginx", 
"cache", "mysql"},
+                                       HealthFilter:    `Service.Tags contains 
"canary"`,
                                        ServiceTags:     []string{"canary", 
"v1"},
                                        NodeMeta:        
map[string]string{"rack": "123"},
                                        TagSeparator:    
consul.DefaultSDConfig.TagSeparator,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prometheus-3.11.1/config/testdata/conf.good.yml 
new/prometheus-3.11.2/config/testdata/conf.good.yml
--- old/prometheus-3.11.1/config/testdata/conf.good.yml 2026-04-07 
16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/config/testdata/conf.good.yml 2026-04-13 
13:39:08.000000000 +0200
@@ -182,6 +182,7 @@
         token: mysecret
         path_prefix: /consul
         services: ["nginx", "cache", "mysql"]
+        health_filter: 'Service.Tags contains "canary"'
         tags: ["canary", "v1"]
         node_meta:
           rack: "123"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prometheus-3.11.1/config/testdata/roundtrip.good.yml 
new/prometheus-3.11.2/config/testdata/roundtrip.good.yml
--- old/prometheus-3.11.1/config/testdata/roundtrip.good.yml    2026-04-07 
16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/config/testdata/roundtrip.good.yml    2026-04-13 
13:39:08.000000000 +0200
@@ -41,6 +41,7 @@
       - server: localhost:1234
         token: <secret>
         services: [nginx, cache, mysql]
+        health_filter: 'Service.Tags contains "canary"'
         tags: [canary, v1]
         node_meta:
           rack: "123"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prometheus-3.11.1/discovery/consul/consul.go 
new/prometheus-3.11.2/discovery/consul/consul.go
--- old/prometheus-3.11.1/discovery/consul/consul.go    2026-04-07 
16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/discovery/consul/consul.go    2026-04-13 
13:39:08.000000000 +0200
@@ -116,9 +116,12 @@
        ServiceTags []string `yaml:"tags,omitempty"`
        // Desired node metadata. As of Consul 1.14, consider `filter` instead.
        NodeMeta map[string]string `yaml:"node_meta,omitempty"`
-       // Consul filter string
-       // See https://www.consul.io/api-docs/catalog#filtering-1, for syntax
+       // Filter expression for the Catalog API.
+       // See 
https://developer.hashicorp.com/consul/api-docs/catalog#filtering for syntax.
        Filter string `yaml:"filter,omitempty"`
+       // Filter expression for the Health API.
+       // See https://developer.hashicorp.com/consul/api-docs/health#filtering 
for syntax.
+       HealthFilter string `yaml:"health_filter,omitempty"`
 
        HTTPClientConfig config.HTTPClientConfig `yaml:",inline"`
 }
@@ -170,20 +173,21 @@
 // Discovery retrieves target information from a Consul server
 // and updates them via watches.
 type Discovery struct {
-       client           *consul.Client
-       clientDatacenter string
-       clientNamespace  string
-       clientPartition  string
-       tagSeparator     string
-       watchedServices  []string // Set of services which will be discovered.
-       watchedTags      []string // Tags used to filter instances of a service.
-       watchedNodeMeta  map[string]string
-       watchedFilter    string
-       allowStale       bool
-       refreshInterval  time.Duration
-       finalizer        func()
-       logger           *slog.Logger
-       metrics          *consulMetrics
+       client              *consul.Client
+       clientDatacenter    string
+       clientNamespace     string
+       clientPartition     string
+       tagSeparator        string
+       watchedServices     []string // Set of services which will be 
discovered.
+       watchedTags         []string // Tags used to filter instances of a 
service.
+       watchedNodeMeta     map[string]string
+       watchedFilter       string
+       watchedHealthFilter string
+       allowStale          bool
+       refreshInterval     time.Duration
+       finalizer           func()
+       logger              *slog.Logger
+       metrics             *consulMetrics
 }
 
 // NewDiscovery returns a new Discovery for the given config.
@@ -218,20 +222,21 @@
                return nil, err
        }
        cd := &Discovery{
-               client:           client,
-               tagSeparator:     conf.TagSeparator,
-               watchedServices:  conf.Services,
-               watchedTags:      conf.ServiceTags,
-               watchedNodeMeta:  conf.NodeMeta,
-               watchedFilter:    conf.Filter,
-               allowStale:       conf.AllowStale,
-               refreshInterval:  time.Duration(conf.RefreshInterval),
-               clientDatacenter: conf.Datacenter,
-               clientNamespace:  conf.Namespace,
-               clientPartition:  conf.Partition,
-               finalizer:        wrapper.CloseIdleConnections,
-               logger:           logger,
-               metrics:          m,
+               client:              client,
+               tagSeparator:        conf.TagSeparator,
+               watchedServices:     conf.Services,
+               watchedTags:         conf.ServiceTags,
+               watchedNodeMeta:     conf.NodeMeta,
+               watchedFilter:       conf.Filter,
+               watchedHealthFilter: conf.HealthFilter,
+               allowStale:          conf.AllowStale,
+               refreshInterval:     time.Duration(conf.RefreshInterval),
+               clientDatacenter:    conf.Datacenter,
+               clientNamespace:     conf.Namespace,
+               clientPartition:     conf.Partition,
+               finalizer:           wrapper.CloseIdleConnections,
+               logger:              logger,
+               metrics:             m,
        }
 
        return cd, nil
@@ -330,7 +335,7 @@
        }
        d.initialize(ctx)
 
-       if len(d.watchedServices) == 0 || len(d.watchedTags) != 0 {
+       if len(d.watchedServices) == 0 || len(d.watchedTags) != 0 || 
d.watchedFilter != "" {
                // We need to watch the catalog.
                ticker := time.NewTicker(d.refreshInterval)
 
@@ -499,7 +504,7 @@
                WaitTime:   watchTimeout,
                AllowStale: srv.discovery.allowStale,
                NodeMeta:   srv.discovery.watchedNodeMeta,
-               Filter:     srv.discovery.watchedFilter,
+               Filter:     srv.discovery.watchedHealthFilter,
        }
 
        t0 := time.Now()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prometheus-3.11.1/discovery/consul/consul_test.go 
new/prometheus-3.11.2/discovery/consul/consul_test.go
--- old/prometheus-3.11.1/discovery/consul/consul_test.go       2026-04-07 
16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/discovery/consul/consul_test.go       2026-04-13 
13:39:08.000000000 +0200
@@ -240,8 +240,6 @@
                        response = ServiceTestAnswer
                case "/v1/health/service/test?wait=120000ms":
                        response = ServiceTestAnswer
-               case 
"/v1/health/service/test?filter=NodeMeta.rack_name+%3D%3D+%222304%22&wait=120000ms":
-                       response = ServiceTestAnswer
                case "/v1/health/service/other?wait=120000ms":
                        response = `[]`
                case 
"/v1/catalog/services?node-meta=rack_name%3A2304&stale=&wait=120000ms":
@@ -297,7 +295,7 @@
 // Watch all the services in the catalog.
 func TestAllServices(t *testing.T) {
        stub, config := newServer(t)
-       defer stub.Close()
+       t.Cleanup(stub.Close)
 
        d := newDiscovery(t, config)
 
@@ -316,7 +314,7 @@
 // targetgroup with no targets is emitted if no services were discovered.
 func TestNoTargets(t *testing.T) {
        stub, config := newServer(t)
-       defer stub.Close()
+       t.Cleanup(stub.Close)
        config.ServiceTags = []string{"missing"}
 
        d := newDiscovery(t, config)
@@ -337,7 +335,7 @@
 // Watch only the test service.
 func TestOneService(t *testing.T) {
        stub, config := newServer(t)
-       defer stub.Close()
+       t.Cleanup(stub.Close)
 
        config.Services = []string{"test"}
        d := newDiscovery(t, config)
@@ -352,7 +350,7 @@
 // Watch the test service with a specific tag and node-meta.
 func TestAllOptions(t *testing.T) {
        stub, config := newServer(t)
-       defer stub.Close()
+       t.Cleanup(stub.Close)
 
        config.Services = []string{"test"}
        config.NodeMeta = map[string]string{"rack_name": "2304"}
@@ -373,16 +371,46 @@
        <-ch
 }
 
-// Watch the test service with a specific tag and node-meta via Filter 
parameter.
+// TestFilterOption verifies that when services and filter are both 
configured, the Catalog API
+// is still called and receives the filter parameter, while the Health API 
does not.
 func TestFilterOption(t *testing.T) {
-       stub, config := newServer(t)
-       defer stub.Close()
+       var (
+               catalogCalled bool
+               catalogFilter string
+               healthCalled  bool
+               healthFilter  string
+       )
 
-       config.Services = []string{"test"}
-       config.Filter = `NodeMeta.rack_name == "2304"`
-       config.Token = "fake-token"
+       stub := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, 
r *http.Request) {
+               w.Header().Add("X-Consul-Index", "1")
+               switch r.URL.Path {
+               case "/v1/agent/self":
+                       w.Write([]byte(AgentAnswer))
+               case "/v1/catalog/services":
+                       catalogCalled = true
+                       catalogFilter = r.URL.Query().Get("filter")
+                       w.Write([]byte(`{"test": []}`))
+               case "/v1/health/service/test":
+                       healthCalled = true
+                       healthFilter = r.URL.Query().Get("filter")
+                       w.Write([]byte(ServiceTestAnswer))
+               default:
+                       t.Errorf("Unhandled consul call: %s", r.URL)
+               }
+       }))
+       t.Cleanup(stub.Close)
 
-       d := newDiscovery(t, config)
+       stuburl, err := url.Parse(stub.URL)
+       require.NoError(t, err)
+
+       cfg := &SDConfig{
+               Server:          stuburl.Host,
+               Services:        []string{"test"},
+               Filter:          `NodeMeta.rack_name == "2304"`,
+               RefreshInterval: model.Duration(1 * time.Second),
+       }
+
+       d := newDiscovery(t, cfg)
 
        ctx, cancel := context.WithCancel(context.Background())
        ch := make(chan []*targetgroup.Group)
@@ -391,43 +419,116 @@
                close(ch)
        }()
        checkOneTarget(t, <-ch)
+       // All handler writes happened-before the channel receive above.
+       require.True(t, catalogCalled, "Catalog endpoint should be called when 
filter is set alongside services.")
+       require.Equal(t, `NodeMeta.rack_name == "2304"`, catalogFilter, 
"Catalog should receive the filter parameter.")
+       require.True(t, healthCalled, "Health endpoint should be called.")
+       require.Empty(t, healthFilter, "Health endpoint should not receive the 
catalog filter.")
        cancel()
+       for range ch {
+       }
 }
 
-// TestFilterOnHealthEndpoint verifies that filter is passed to health service 
endpoint.
-func TestFilterOnHealthEndpoint(t *testing.T) {
-       filterReceived := false
+// TestHealthFilterOption verifies that health_filter is passed to the Health 
API and not to
+// the Catalog API.
+func TestHealthFilterOption(t *testing.T) {
+       var (
+               catalogCalled bool
+               catalogFilter string
+               healthCalled  bool
+               healthFilter  string
+       )
+
        stub := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, 
r *http.Request) {
-               response := ""
+               w.Header().Add("X-Consul-Index", "1")
                switch r.URL.Path {
                case "/v1/agent/self":
-                       response = AgentAnswer
+                       w.Write([]byte(AgentAnswer))
+               case "/v1/catalog/services":
+                       catalogCalled = true
+                       catalogFilter = r.URL.Query().Get("filter")
+                       w.Write([]byte(`{"test": []}`))
                case "/v1/health/service/test":
-                       // Verify filter parameter is present in the query
-                       filter := r.URL.Query().Get("filter")
-                       if filter == `Node.Meta.rack_name == "2304"` {
-                               filterReceived = true
-                       }
-                       response = ServiceTestAnswer
+                       healthCalled = true
+                       healthFilter = r.URL.Query().Get("filter")
+                       w.Write([]byte(ServiceTestAnswer))
                default:
                        t.Errorf("Unhandled consul call: %s", r.URL)
                }
+       }))
+       t.Cleanup(stub.Close)
+
+       stuburl, err := url.Parse(stub.URL)
+       require.NoError(t, err)
+
+       // No services configured: catalog path is always used, allowing us to 
assert
+       // that health_filter is not forwarded to the Catalog API.
+       cfg := &SDConfig{
+               Server:          stuburl.Host,
+               HealthFilter:    `Service.Tags contains "canary"`,
+               RefreshInterval: model.Duration(1 * time.Second),
+       }
+
+       d := newDiscovery(t, cfg)
+
+       ctx, cancel := context.WithCancel(context.Background())
+       ch := make(chan []*targetgroup.Group)
+       go func() {
+               d.Run(ctx, ch)
+               close(ch)
+       }()
+       checkOneTarget(t, <-ch)
+       // All handler writes happened-before the channel receive above.
+       require.True(t, catalogCalled, "Catalog endpoint should be called.")
+       require.Empty(t, catalogFilter, "Catalog should not receive the 
health_filter parameter.")
+       require.True(t, healthCalled, "Health endpoint should be called.")
+       require.Equal(t, `Service.Tags contains "canary"`, healthFilter, 
"Health endpoint should receive the health_filter parameter.")
+       cancel()
+       for range ch {
+       }
+}
+
+// TestBothFiltersOption verifies that when both filter and health_filter are 
configured,
+// each filter is sent exclusively to its respective API endpoint.
+func TestBothFiltersOption(t *testing.T) {
+       var (
+               catalogCalled bool
+               catalogFilter string
+               healthCalled  bool
+               healthFilter  string
+       )
+
+       stub := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, 
r *http.Request) {
                w.Header().Add("X-Consul-Index", "1")
-               w.Write([]byte(response))
+               switch r.URL.Path {
+               case "/v1/agent/self":
+                       w.Write([]byte(AgentAnswer))
+               case "/v1/catalog/services":
+                       catalogCalled = true
+                       catalogFilter = r.URL.Query().Get("filter")
+                       w.Write([]byte(`{"test": []}`))
+               case "/v1/health/service/test":
+                       healthCalled = true
+                       healthFilter = r.URL.Query().Get("filter")
+                       w.Write([]byte(ServiceTestAnswer))
+               default:
+                       t.Errorf("Unhandled consul call: %s", r.URL)
+               }
        }))
-       defer stub.Close()
+       t.Cleanup(stub.Close)
 
        stuburl, err := url.Parse(stub.URL)
        require.NoError(t, err)
 
-       config := &SDConfig{
+       cfg := &SDConfig{
                Server:          stuburl.Host,
                Services:        []string{"test"},
-               Filter:          `Node.Meta.rack_name == "2304"`,
+               Filter:          `NodeMeta.rack_name == "2304"`,
+               HealthFilter:    `Service.Tags contains "canary"`,
                RefreshInterval: model.Duration(1 * time.Second),
        }
 
-       d := newDiscovery(t, config)
+       d := newDiscovery(t, cfg)
 
        ctx, cancel := context.WithCancel(context.Background())
        ch := make(chan []*targetgroup.Group)
@@ -436,10 +537,14 @@
                close(ch)
        }()
        checkOneTarget(t, <-ch)
+       // All handler writes happened-before the channel receive above.
+       require.True(t, catalogCalled, "Catalog endpoint should be called when 
filter is set.")
+       require.Equal(t, `NodeMeta.rack_name == "2304"`, catalogFilter, 
"Catalog should receive only the catalog filter.")
+       require.True(t, healthCalled, "Health endpoint should be called.")
+       require.Equal(t, `Service.Tags contains "canary"`, healthFilter, 
"Health endpoint should receive only the health_filter.")
        cancel()
-
-       // Verify the filter was actually sent to the health endpoint
-       require.True(t, filterReceived, "Filter parameter should be sent to 
health service endpoint")
+       for range ch {
+       }
 }
 
 func TestGetDatacenterShouldReturnError(t *testing.T) {
@@ -471,7 +576,7 @@
                        Token:           "fake-token",
                        RefreshInterval: model.Duration(1 * time.Second),
                }
-               defer stub.Close()
+               t.Cleanup(stub.Close)
                d := newDiscovery(t, config)
 
                // Should be empty if not initialized.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/prometheus-3.11.1/docs/configuration/configuration.md 
new/prometheus-3.11.2/docs/configuration/configuration.md
--- old/prometheus-3.11.1/docs/configuration/configuration.md   2026-04-07 
16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/docs/configuration/configuration.md   2026-04-13 
13:39:08.000000000 +0200
@@ -1417,7 +1417,17 @@
 ### `<consul_sd_config>`
 
 Consul SD configurations allow retrieving scrape targets from 
[Consul's](https://www.consul.io)
-Catalog API.
+service catalog. Discovery uses two Consul API endpoints:
+
+1. The [Catalog API](https://developer.hashicorp.com/consul/api-docs/catalog) 
to list services
+   (used when `services` is empty, or when `tags` or `filter` are set).
+2. The [Health API](https://developer.hashicorp.com/consul/api-docs/health) to 
retrieve service
+   instances and their health status.
+
+Because these two APIs have different filtering field schemas, Prometheus 
exposes separate filter
+options for each: `filter` applies to the Catalog API and `health_filter` 
applies to the Health API.
+For example, tags are exposed as `ServiceTags` in the Catalog API but as 
`Service.Tags` in the
+Health API.
 
 The following meta labels are available on targets during 
[relabeling](#relabel_config):
 
@@ -1457,17 +1467,18 @@
 services:
   [ - <string> ]
 
-# A Consul Filter expression used to filter the catalog results
-# See https://www.consul.io/api-docs/catalog#list-services to know more
-# about the filter expressions that can be used.
+# Filter expression for the Catalog API. See 
https://developer.hashicorp.com/consul/api-docs/catalog#filtering for syntax.
 [ filter: <string> ]
 
-# The `tags` and `node_meta` fields are deprecated in Consul in favor of 
`filter`.
+# Filter expression for the Health API. See 
https://developer.hashicorp.com/consul/api-docs/health#filtering for syntax.
+[ health_filter: <string> ]
+
+# The `tags` and `node_meta` fields are deprecated in favor of `filter` and 
`health_filter`.
 # An optional list of tags used to filter nodes for a given service. Services 
must contain all tags in the list.
 tags:
   [ - <string> ]
 
-# Node metadata key/value pairs to filter nodes for a given service. As of 
Consul 1.14, consider `filter` instead.
+# Node metadata key/value pairs to filter nodes for a given service. As of 
Consul 1.14, consider `filter` or `health_filter` instead.
 [ node_meta:
   [ <string>: <string> ... ] ]
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prometheus-3.11.1/web/ui/mantine-ui/package.json 
new/prometheus-3.11.2/web/ui/mantine-ui/package.json
--- old/prometheus-3.11.1/web/ui/mantine-ui/package.json        2026-04-07 
16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/web/ui/mantine-ui/package.json        2026-04-13 
13:39:08.000000000 +0200
@@ -1,7 +1,7 @@
 {
   "name": "@prometheus-io/mantine-ui",
   "private": true,
-  "version": "0.311.1",
+  "version": "0.311.2",
   "type": "module",
   "scripts": {
     "start": "vite",
@@ -28,7 +28,7 @@
     "@microsoft/fetch-event-source": "^2.0.1",
     "@nexucis/fuzzy": "^0.5.1",
     "@nexucis/kvsearch": "^0.9.1",
-    "@prometheus-io/codemirror-promql": "0.311.1",
+    "@prometheus-io/codemirror-promql": "0.311.2",
     "@reduxjs/toolkit": "^2.11.2",
     "@tabler/icons-react": "^3.40.0",
     "@tanstack/react-query": "^5.95.2",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/prometheus-3.11.1/web/ui/mantine-ui/src/pages/query/uPlotChartHelpers.ts 
new/prometheus-3.11.2/web/ui/mantine-ui/src/pages/query/uPlotChartHelpers.ts
--- 
old/prometheus-3.11.1/web/ui/mantine-ui/src/pages/query/uPlotChartHelpers.ts    
    2026-04-07 16:55:05.000000000 +0200
+++ 
new/prometheus-3.11.2/web/ui/mantine-ui/src/pages/query/uPlotChartHelpers.ts    
    2026-04-13 13:39:08.000000000 +0200
@@ -76,7 +76,7 @@
                 .filter((k) => k !== "__name__")
                 .map(
                   (k) =>
-                    `<div><strong>${escapeHTML(k)}</strong>: 
${escapeHTML(labels[k])}</div>`
+                    `<div><strong>${escapeHTML(k)}</strong>: 
${escapeHTML(labels[k])}</div>`,
                 )
                 .join("")}
             </div>`;
@@ -153,7 +153,7 @@
             <div class="date">${formatTimestamp(ts, useLocalTime)}</div>
             <div class="series-value">
               <span class="detail-swatch" style="background-color: 
${color}"></span>
-              <span>${labels.__name__ ? labels.__name__ + ": " : " 
"}<strong>${value}</strong></span>
+              <span>${labels.__name__ ? escapeHTML(labels.__name__) + ": " : " 
"}<strong>${value}</strong></span>
             </div>
             ${formatLabels(labels)}
           `.trimEnd();
@@ -193,7 +193,7 @@
   u: uPlot,
   values: string[],
   axisIdx: number,
-  cycleNum: number
+  cycleNum: number,
 ) => {
   const axis = u.axes[axisIdx];
 
@@ -208,7 +208,7 @@
   // Find longest tick text.
   const longestVal = (values ?? []).reduce(
     (acc, val) => (val.length > acc.length ? val : acc),
-    ""
+    "",
   );
 
   if (longestVal != "") {
@@ -228,7 +228,7 @@
   u: uPlot,
   seriesIdx: number,
   show: boolean,
-  gaps?: null | number[][]
+  gaps?: null | number[][],
 ) => {
   const filtered = [];
 
@@ -287,7 +287,7 @@
   useLocalTime: boolean,
   yAxisMin: number | null,
   light: boolean,
-  onSelectRange: (_start: number, _end: number) => void
+  onSelectRange: (_start: number, _end: number) => void,
 ): uPlot.Options => ({
   width: width - 30,
   height: 550,
@@ -314,7 +314,7 @@
     markers: {
       fill: (
         _u: uPlot,
-        seriesIdx: number
+        seriesIdx: number,
       ): CSSStyleDeclaration["borderColor"] =>
         // Because the index here is coming from uPlot, we need to subtract 1. 
Series 0
         // represents the X axis, so we need to skip it.
@@ -411,7 +411,7 @@
         // @ts-expect-error - uPlot doesn't have a field for labels, but we 
just attach some anyway.
         labels: r.metric,
         stroke: getSeriesColor(idx, light),
-      })
+      }),
     ),
   ],
   hooks: {
@@ -421,7 +421,7 @@
         const leftVal = self.posToVal(self.select.left, "x");
         const rightVal = Math.max(
           self.posToVal(self.select.left + self.select.width, "x"),
-          leftVal + 1
+          leftVal + 1,
         );
 
         onSelectRange(leftVal, rightVal);
@@ -441,7 +441,7 @@
   inputData: RangeSamples[],
   startTime: number,
   endTime: number,
-  resolution: number
+  resolution: number,
 ): uPlot.AlignedData => {
   const timeData: number[] = [];
   for (let t = startTime; t <= endTime; t += resolution) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/prometheus-3.11.1/web/ui/module/codemirror-promql/package.json 
new/prometheus-3.11.2/web/ui/module/codemirror-promql/package.json
--- old/prometheus-3.11.1/web/ui/module/codemirror-promql/package.json  
2026-04-07 16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/web/ui/module/codemirror-promql/package.json  
2026-04-13 13:39:08.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@prometheus-io/codemirror-promql",
-  "version": "0.311.1",
+  "version": "0.311.2",
   "description": "a CodeMirror mode for the PromQL language",
   "types": "dist/esm/index.d.ts",
   "module": "dist/esm/index.js",
@@ -29,7 +29,7 @@
   },
   "homepage": 
"https://github.com/prometheus/prometheus/blob/main/web/ui/module/codemirror-promql/README.md";,
   "dependencies": {
-    "@prometheus-io/lezer-promql": "0.311.1",
+    "@prometheus-io/lezer-promql": "0.311.2",
     "lru-cache": "^11.2.7"
   },
   "devDependencies": {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/prometheus-3.11.1/web/ui/module/lezer-promql/package.json 
new/prometheus-3.11.2/web/ui/module/lezer-promql/package.json
--- old/prometheus-3.11.1/web/ui/module/lezer-promql/package.json       
2026-04-07 16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/web/ui/module/lezer-promql/package.json       
2026-04-13 13:39:08.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@prometheus-io/lezer-promql",
-  "version": "0.311.1",
+  "version": "0.311.2",
   "description": "lezer-based PromQL grammar",
   "main": "dist/index.cjs",
   "type": "module",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prometheus-3.11.1/web/ui/package-lock.json 
new/prometheus-3.11.2/web/ui/package-lock.json
--- old/prometheus-3.11.1/web/ui/package-lock.json      2026-04-07 
16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/web/ui/package-lock.json      2026-04-13 
13:39:08.000000000 +0200
@@ -1,12 +1,12 @@
 {
   "name": "prometheus-io",
-  "version": "0.311.1",
+  "version": "0.311.2",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
     "": {
       "name": "prometheus-io",
-      "version": "0.311.1",
+      "version": "0.311.2",
       "workspaces": [
         "mantine-ui",
         "module/*"
@@ -24,7 +24,7 @@
     },
     "mantine-ui": {
       "name": "@prometheus-io/mantine-ui",
-      "version": "0.311.1",
+      "version": "0.311.2",
       "dependencies": {
         "@codemirror/autocomplete": "^6.20.1",
         "@codemirror/language": "^6.12.3",
@@ -42,7 +42,7 @@
         "@microsoft/fetch-event-source": "^2.0.1",
         "@nexucis/fuzzy": "^0.5.1",
         "@nexucis/kvsearch": "^0.9.1",
-        "@prometheus-io/codemirror-promql": "0.311.1",
+        "@prometheus-io/codemirror-promql": "0.311.2",
         "@reduxjs/toolkit": "^2.11.2",
         "@tabler/icons-react": "^3.40.0",
         "@tanstack/react-query": "^5.95.2",
@@ -172,10 +172,10 @@
     },
     "module/codemirror-promql": {
       "name": "@prometheus-io/codemirror-promql",
-      "version": "0.311.1",
+      "version": "0.311.2",
       "license": "Apache-2.0",
       "dependencies": {
-        "@prometheus-io/lezer-promql": "0.311.1",
+        "@prometheus-io/lezer-promql": "0.311.2",
         "lru-cache": "^11.2.7"
       },
       "devDependencies": {
@@ -205,7 +205,7 @@
     },
     "module/lezer-promql": {
       "name": "@prometheus-io/lezer-promql",
-      "version": "0.311.1",
+      "version": "0.311.2",
       "license": "Apache-2.0",
       "devDependencies": {
         "@lezer/generator": "^1.8.0",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/prometheus-3.11.1/web/ui/package.json 
new/prometheus-3.11.2/web/ui/package.json
--- old/prometheus-3.11.1/web/ui/package.json   2026-04-07 16:55:05.000000000 
+0200
+++ new/prometheus-3.11.2/web/ui/package.json   2026-04-13 13:39:08.000000000 
+0200
@@ -1,7 +1,7 @@
 {
   "name": "prometheus-io",
   "description": "Monorepo for the Prometheus UI",
-  "version": "0.311.1",
+  "version": "0.311.2",
   "private": true,
   "scripts": {
     "build": "bash build_ui.sh --all",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/prometheus-3.11.1/web/ui/react-app/src/pages/graph/GraphHelpers.ts 
new/prometheus-3.11.2/web/ui/react-app/src/pages/graph/GraphHelpers.ts
--- old/prometheus-3.11.1/web/ui/react-app/src/pages/graph/GraphHelpers.ts      
2026-04-07 16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/web/ui/react-app/src/pages/graph/GraphHelpers.ts      
2026-04-13 13:39:08.000000000 +0200
@@ -118,10 +118,10 @@
         const formatLabels = (labels: { [key: string]: string }): string => `
             <div class="labels">
               ${Object.keys(labels).length === 0 ? '<div class="mb-1 
font-italic">no labels</div>' : ''}
-              ${labels['__name__'] ? `<div 
class="mb-1"><strong>${labels['__name__']}</strong></div>` : ''}
+              ${labels['__name__'] ? `<div 
class="mb-1"><strong>${escapeHTML(labels['__name__'])}</strong></div>` : ''}
               ${Object.keys(labels)
                 .filter((k) => k !== '__name__')
-                .map((k) => `<div class="mb-1"><strong>${k}</strong>: 
${escapeHTML(labels[k])}</div>`)
+                .map((k) => `<div 
class="mb-1"><strong>${escapeHTML(k)}</strong>: ${escapeHTML(labels[k])}</div>`)
                 .join('')}
             </div>`;
 
@@ -129,7 +129,7 @@
             <div class="date">${dateTime.format('YYYY-MM-DD HH:mm:ss Z')}</div>
             <div>
               <span class="detail-swatch" style="background-color: 
${color}"></span>
-              <span>${labels.__name__ || 'value'}: 
<strong>${yval}</strong></span>
+              <span>${labels.__name__ ? escapeHTML(labels.__name__) : 
'value'}: <strong>${yval}</strong></span>
             </div>
             <div class="mt-2 mb-1 font-weight-bold">${'seriesLabels' in both ? 
'Trace exemplar:' : 'Series:'}</div>
             ${formatLabels(labels)}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/prometheus-3.11.1/web/ui/react-app/src/pages/graph/MetricsExplorer.tsx 
new/prometheus-3.11.2/web/ui/react-app/src/pages/graph/MetricsExplorer.tsx
--- old/prometheus-3.11.1/web/ui/react-app/src/pages/graph/MetricsExplorer.tsx  
2026-04-07 16:55:05.000000000 +0200
+++ new/prometheus-3.11.2/web/ui/react-app/src/pages/graph/MetricsExplorer.tsx  
2026-04-13 13:39:08.000000000 +0200
@@ -2,7 +2,7 @@
 import { Modal, ModalBody, ModalHeader, Input } from 'reactstrap';
 import { Fuzzy, FuzzyResult } from '@nexucis/fuzzy';
 
-const fuz = new Fuzzy({ pre: '<strong>', post: '</strong>', shouldSort: true 
});
+const fuz = new Fuzzy({ pre: '<strong>', post: '</strong>', shouldSort: true, 
escapeHTML: true });
 
 interface MetricsExplorerProps {
   show: boolean;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/prometheus-3.11.1/web/ui/react-app/src/vendor/flot/jquery.flot.heatmap.js 
new/prometheus-3.11.2/web/ui/react-app/src/vendor/flot/jquery.flot.heatmap.js
--- 
old/prometheus-3.11.1/web/ui/react-app/src/vendor/flot/jquery.flot.heatmap.js   
    2026-04-07 16:55:05.000000000 +0200
+++ 
new/prometheus-3.11.2/web/ui/react-app/src/vendor/flot/jquery.flot.heatmap.js   
    2026-04-13 13:39:08.000000000 +0200
@@ -6,6 +6,7 @@
 
 import moment from 'moment-timezone';
 import {formatValue} from "../../pages/graph/GraphHelpers";
+import {escapeHTML} from '../../utils';
 
 const TOOLTIP_ID = 'heatmap-tooltip';
 const GRADIENT_STEPS = 16;
@@ -82,7 +83,7 @@
     tooltip.className = cssClass;
 
     const timeHtml = `<div class="date">${dateTime.join('<br>')}</div>`
-    const labelHtml = `<div>Bucket: ${label || 'value'}</div>`
+    const labelHtml = `<div>Bucket: ${label ? escapeHTML(label) : 
'value'}</div>`
     const valueHtml = `<div>Value: <strong>${value}</strong></div>`
     tooltip.innerHTML = 
`<div>${timeHtml}<div>${labelHtml}${valueHtml}</div></div>`;
 

++++++ prometheus.obsinfo ++++++
--- /var/tmp/diff_new_pack.rFgTBP/_old  2026-04-23 17:03:56.195076237 +0200
+++ /var/tmp/diff_new_pack.rFgTBP/_new  2026-04-23 17:03:56.199076402 +0200
@@ -1,5 +1,5 @@
 name: prometheus
-version: 3.11.1
-mtime: 1775573705
-commit: 1bd2f3a9fdedf52e6f613449cc4c50e86ca24676
+version: 3.11.2
+mtime: 1776080348
+commit: f0f0fdd679dcd6df320b0558b20919f7cd44c407
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/golang-github-prometheus-prometheus/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.golang-github-prometheus-prometheus.new.11940/vendor.tar.gz
 differ: char 13, line 1

Reply via email to