mirror of
https://github.com/prometheus/prometheus.git
synced 2026-06-09 08:32:26 -04:00
Merge pull request #18518 from prometheus/release-3.11
Some checks are pending
buf.build / lint and publish (push) Waiting to run
CI / Go tests (push) Waiting to run
CI / More Go tests (push) Waiting to run
CI / Go tests for Prometheus upgrades and downgrades (push) Waiting to run
CI / Go tests with previous Go version (push) Waiting to run
CI / UI tests (push) Waiting to run
CI / Go tests on Windows (push) Waiting to run
CI / Mixins tests (push) Waiting to run
CI / Compliance testing (push) Waiting to run
CI / Build Prometheus for common architectures (push) Waiting to run
CI / Build Prometheus for all architectures (push) Waiting to run
CI / Report status of build Prometheus for all architectures (push) Blocked by required conditions
CI / Check generated parser (push) Waiting to run
CI / golangci-lint (push) Waiting to run
CI / fuzzing (push) Waiting to run
CI / codeql (push) Waiting to run
CI / Publish main branch artifacts (push) Blocked by required conditions
CI / Publish release artefacts (push) Blocked by required conditions
CI / Publish UI on npm Registry (push) Blocked by required conditions
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
Some checks are pending
buf.build / lint and publish (push) Waiting to run
CI / Go tests (push) Waiting to run
CI / More Go tests (push) Waiting to run
CI / Go tests for Prometheus upgrades and downgrades (push) Waiting to run
CI / Go tests with previous Go version (push) Waiting to run
CI / UI tests (push) Waiting to run
CI / Go tests on Windows (push) Waiting to run
CI / Mixins tests (push) Waiting to run
CI / Compliance testing (push) Waiting to run
CI / Build Prometheus for common architectures (push) Waiting to run
CI / Build Prometheus for all architectures (push) Waiting to run
CI / Report status of build Prometheus for all architectures (push) Blocked by required conditions
CI / Check generated parser (push) Waiting to run
CI / golangci-lint (push) Waiting to run
CI / fuzzing (push) Waiting to run
CI / codeql (push) Waiting to run
CI / Publish main branch artifacts (push) Blocked by required conditions
CI / Publish release artefacts (push) Blocked by required conditions
CI / Publish UI on npm Registry (push) Blocked by required conditions
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
Merge back release 3.11.2
This commit is contained in:
commit
12de1243c0
13 changed files with 229 additions and 97 deletions
|
|
@ -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
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
3.11.1
|
||||
3.11.2
|
||||
|
|
|
|||
|
|
@ -482,6 +482,7 @@ var expectedConf = &Config{
|
|||
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,
|
||||
|
|
|
|||
1
config/testdata/conf.good.yml
vendored
1
config/testdata/conf.good.yml
vendored
|
|
@ -182,6 +182,7 @@ scrape_configs:
|
|||
token: mysecret
|
||||
path_prefix: /consul
|
||||
services: ["nginx", "cache", "mysql"]
|
||||
health_filter: 'Service.Tags contains "canary"'
|
||||
tags: ["canary", "v1"]
|
||||
node_meta:
|
||||
rack: "123"
|
||||
|
|
|
|||
1
config/testdata/roundtrip.good.yml
vendored
1
config/testdata/roundtrip.good.yml
vendored
|
|
@ -41,6 +41,7 @@ scrape_configs:
|
|||
- server: localhost:1234
|
||||
token: <secret>
|
||||
services: [nginx, cache, mysql]
|
||||
health_filter: 'Service.Tags contains "canary"'
|
||||
tags: [canary, v1]
|
||||
node_meta:
|
||||
rack: "123"
|
||||
|
|
|
|||
|
|
@ -116,9 +116,12 @@ type SDConfig struct {
|
|||
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 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(any) error) error {
|
|||
// 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 @@ func NewDiscovery(conf *SDConfig, logger *slog.Logger, metrics discovery.Discove
|
|||
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 @@ func (d *Discovery) Run(ctx context.Context, ch chan<- []*targetgroup.Group) {
|
|||
}
|
||||
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 @@ func (srv *consulService) watch(ctx context.Context, ch chan<- []*targetgroup.Gr
|
|||
WaitTime: watchTimeout,
|
||||
AllowStale: srv.discovery.allowStale,
|
||||
NodeMeta: srv.discovery.watchedNodeMeta,
|
||||
Filter: srv.discovery.watchedFilter,
|
||||
Filter: srv.discovery.watchedHealthFilter,
|
||||
}
|
||||
|
||||
t0 := time.Now()
|
||||
|
|
|
|||
|
|
@ -240,8 +240,6 @@ func newServer(t *testing.T) (*httptest.Server, *SDConfig) {
|
|||
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 @@ func checkOneTarget(t *testing.T, tg []*targetgroup.Group) {
|
|||
// 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 @@ func TestAllServices(t *testing.T) {
|
|||
// 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 @@ func TestNoTargets(t *testing.T) {
|
|||
// 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 @@ func TestOneService(t *testing.T) {
|
|||
// 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,61 +371,46 @@ func TestAllOptions(t *testing.T) {
|
|||
<-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"
|
||||
|
||||
d := newDiscovery(t, config)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ch := make(chan []*targetgroup.Group)
|
||||
go func() {
|
||||
d.Run(ctx, ch)
|
||||
close(ch)
|
||||
}()
|
||||
checkOneTarget(t, <-ch)
|
||||
cancel()
|
||||
}
|
||||
|
||||
// TestFilterOnHealthEndpoint verifies that filter is passed to health service endpoint.
|
||||
func TestFilterOnHealthEndpoint(t *testing.T) {
|
||||
filterReceived := false
|
||||
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)
|
||||
}
|
||||
w.Header().Add("X-Consul-Index", "1")
|
||||
w.Write([]byte(response))
|
||||
}))
|
||||
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"`,
|
||||
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 +419,132 @@ func TestFilterOnHealthEndpoint(t *testing.T) {
|
|||
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 {
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the filter was actually sent to the health endpoint
|
||||
require.True(t, filterReceived, "Filter parameter should be sent to health service endpoint")
|
||||
// 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) {
|
||||
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)
|
||||
|
||||
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")
|
||||
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)
|
||||
|
||||
stuburl, err := url.Parse(stub.URL)
|
||||
require.NoError(t, err)
|
||||
|
||||
cfg := &SDConfig{
|
||||
Server: stuburl.Host,
|
||||
Services: []string{"test"},
|
||||
Filter: `NodeMeta.rack_name == "2304"`,
|
||||
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 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()
|
||||
for range ch {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDatacenterShouldReturnError(t *testing.T) {
|
||||
|
|
@ -471,7 +576,7 @@ func TestGetDatacenterShouldReturnError(t *testing.T) {
|
|||
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.
|
||||
|
|
|
|||
|
|
@ -1421,7 +1421,17 @@ subscription_id: <string>
|
|||
### `<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):
|
||||
|
||||
|
|
@ -1461,17 +1471,18 @@ The following meta labels are available on targets during [relabeling](#relabel_
|
|||
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> ... ] ]
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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": {
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
14
web/ui/package-lock.json
generated
14
web/ui/package-lock.json
generated
|
|
@ -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",
|
||||
|
|
@ -88,10 +88,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": {
|
||||
|
|
@ -121,7 +121,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",
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in a new issue