From 4f2bc1d7145172b18f47d9d119e73d0e3f140384 Mon Sep 17 00:00:00 2001 From: Sanchit2662 Date: Sun, 1 Mar 2026 16:53:59 +0530 Subject: [PATCH 001/170] config: validate remote_write queue_config fields Signed-off-by: Sanchit2662 --- config/config.go | 27 +++++++++++++++++++ config/config_test.go | 12 +++++++++ ...te_queue_max_backoff_less_than_min.bad.yml | 5 ++++ ...te_queue_max_samples_per_send_zero.bad.yml | 4 +++ ..._queue_min_shards_greater_than_max.bad.yml | 5 ++++ 5 files changed, 53 insertions(+) create mode 100644 config/testdata/remote_write_queue_max_backoff_less_than_min.bad.yml create mode 100644 config/testdata/remote_write_queue_max_samples_per_send_zero.bad.yml create mode 100644 config/testdata/remote_write_queue_min_shards_greater_than_max.bad.yml diff --git a/config/config.go b/config/config.go index 0ebebc26d5..1655c61785 100644 --- a/config/config.go +++ b/config/config.go @@ -1474,6 +1474,10 @@ func (c *RemoteWriteConfig) UnmarshalYAML(unmarshal func(any) error) error { return err } + if err := c.QueueConfig.Validate(); err != nil { + return err + } + return validateAuthConfigs(c) } @@ -1566,6 +1570,29 @@ type QueueConfig struct { SampleAgeLimit model.Duration `yaml:"sample_age_limit,omitempty"` } +// Validate checks QueueConfig fields for invalid values. +func (c *QueueConfig) Validate() error { + if c.MaxShards <= 0 { + return errors.New("remote write queue max_shards must be positive") + } + if c.MinShards <= 0 { + return errors.New("remote write queue min_shards must be positive") + } + if c.MinShards > c.MaxShards { + return errors.New("remote write queue min_shards must not be greater than max_shards") + } + if c.MaxSamplesPerSend <= 0 { + return errors.New("remote write queue max_samples_per_send must be positive") + } + if c.Capacity <= 0 { + return errors.New("remote write queue capacity must be positive") + } + if c.MaxBackoff < c.MinBackoff { + return errors.New("remote write queue max_backoff must not be less than min_backoff") + } + return nil +} + // MetadataConfig is the configuration for sending metadata to remote // storage. type MetadataConfig struct { diff --git a/config/config_test.go b/config/config_test.go index 43c56a501f..ab9f48e36c 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -2414,6 +2414,18 @@ var expectedErrors = []struct { filename: "remote_write_dup.bad.yml", errMsg: `found multiple remote write configs with job name "queue1"`, }, + { + filename: "remote_write_queue_max_samples_per_send_zero.bad.yml", + errMsg: `remote write queue max_samples_per_send must be positive`, + }, + { + filename: "remote_write_queue_min_shards_greater_than_max.bad.yml", + errMsg: `remote write queue min_shards must not be greater than max_shards`, + }, + { + filename: "remote_write_queue_max_backoff_less_than_min.bad.yml", + errMsg: `remote write queue max_backoff must not be less than min_backoff`, + }, { filename: "remote_read_dup.bad.yml", errMsg: `found multiple remote read configs with job name "queue1"`, diff --git a/config/testdata/remote_write_queue_max_backoff_less_than_min.bad.yml b/config/testdata/remote_write_queue_max_backoff_less_than_min.bad.yml new file mode 100644 index 0000000000..e0629b206e --- /dev/null +++ b/config/testdata/remote_write_queue_max_backoff_less_than_min.bad.yml @@ -0,0 +1,5 @@ +remote_write: + - url: http://localhost:9090/api/v1/write + queue_config: + min_backoff: 10s + max_backoff: 1s diff --git a/config/testdata/remote_write_queue_max_samples_per_send_zero.bad.yml b/config/testdata/remote_write_queue_max_samples_per_send_zero.bad.yml new file mode 100644 index 0000000000..301e733632 --- /dev/null +++ b/config/testdata/remote_write_queue_max_samples_per_send_zero.bad.yml @@ -0,0 +1,4 @@ +remote_write: + - url: http://localhost:9090/api/v1/write + queue_config: + max_samples_per_send: 0 diff --git a/config/testdata/remote_write_queue_min_shards_greater_than_max.bad.yml b/config/testdata/remote_write_queue_min_shards_greater_than_max.bad.yml new file mode 100644 index 0000000000..020ecde766 --- /dev/null +++ b/config/testdata/remote_write_queue_min_shards_greater_than_max.bad.yml @@ -0,0 +1,5 @@ +remote_write: + - url: http://localhost:9090/api/v1/write + queue_config: + min_shards: 100 + max_shards: 10 From 8881d0c12beb37ebac07a83106961a714d63d9f8 Mon Sep 17 00:00:00 2001 From: Sanchit2662 Date: Wed, 4 Mar 2026 16:18:45 +0530 Subject: [PATCH 002/170] config: add missing queue_config validation test cases Signed-off-by: Sanchit2662 --- config/config_test.go | 12 ++++++++++++ .../remote_write_queue_capacity_zero.bad.yml | 4 ++++ .../remote_write_queue_max_shards_zero.bad.yml | 4 ++++ .../remote_write_queue_min_shards_zero.bad.yml | 4 ++++ 4 files changed, 24 insertions(+) create mode 100644 config/testdata/remote_write_queue_capacity_zero.bad.yml create mode 100644 config/testdata/remote_write_queue_max_shards_zero.bad.yml create mode 100644 config/testdata/remote_write_queue_min_shards_zero.bad.yml diff --git a/config/config_test.go b/config/config_test.go index ab9f48e36c..2c5665641b 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -2418,6 +2418,18 @@ var expectedErrors = []struct { filename: "remote_write_queue_max_samples_per_send_zero.bad.yml", errMsg: `remote write queue max_samples_per_send must be positive`, }, + { + filename: "remote_write_queue_max_shards_zero.bad.yml", + errMsg: `remote write queue max_shards must be positive`, + }, + { + filename: "remote_write_queue_min_shards_zero.bad.yml", + errMsg: `remote write queue min_shards must be positive`, + }, + { + filename: "remote_write_queue_capacity_zero.bad.yml", + errMsg: `remote write queue capacity must be positive`, + }, { filename: "remote_write_queue_min_shards_greater_than_max.bad.yml", errMsg: `remote write queue min_shards must not be greater than max_shards`, diff --git a/config/testdata/remote_write_queue_capacity_zero.bad.yml b/config/testdata/remote_write_queue_capacity_zero.bad.yml new file mode 100644 index 0000000000..775b1e21a9 --- /dev/null +++ b/config/testdata/remote_write_queue_capacity_zero.bad.yml @@ -0,0 +1,4 @@ +remote_write: + - url: http://localhost:9090/api/v1/write + queue_config: + capacity: 0 diff --git a/config/testdata/remote_write_queue_max_shards_zero.bad.yml b/config/testdata/remote_write_queue_max_shards_zero.bad.yml new file mode 100644 index 0000000000..5fd362e692 --- /dev/null +++ b/config/testdata/remote_write_queue_max_shards_zero.bad.yml @@ -0,0 +1,4 @@ +remote_write: + - url: http://localhost:9090/api/v1/write + queue_config: + max_shards: 0 diff --git a/config/testdata/remote_write_queue_min_shards_zero.bad.yml b/config/testdata/remote_write_queue_min_shards_zero.bad.yml new file mode 100644 index 0000000000..a925449c4a --- /dev/null +++ b/config/testdata/remote_write_queue_min_shards_zero.bad.yml @@ -0,0 +1,4 @@ +remote_write: + - url: http://localhost:9090/api/v1/write + queue_config: + min_shards: 0 From c588fd2338a76579facf0cc0f8fe8efa238bbb25 Mon Sep 17 00:00:00 2001 From: Charles Korn Date: Mon, 16 Mar 2026 16:47:37 +1100 Subject: [PATCH 003/170] chore: document supported formats for duration query request parameters in OpenAPI spec Signed-off-by: Charles Korn --- web/api/v1/openapi_helpers.go | 18 +++++++++ web/api/v1/openapi_paths.go | 10 ++--- web/api/v1/testdata/openapi_3.1_golden.yaml | 45 ++++++++++++++++++--- web/api/v1/testdata/openapi_3.2_golden.yaml | 45 ++++++++++++++++++--- 4 files changed, 103 insertions(+), 15 deletions(-) diff --git a/web/api/v1/openapi_helpers.go b/web/api/v1/openapi_helpers.go index 76f6001693..fd00567194 100644 --- a/web/api/v1/openapi_helpers.go +++ b/web/api/v1/openapi_helpers.go @@ -168,6 +168,24 @@ func timestampSchema() *base.SchemaProxy { }) } +func durationSchema() *base.SchemaProxy { + return base.CreateSchemaProxy(&base.Schema{ + OneOf: []*base.SchemaProxy{ + base.CreateSchemaProxy(&base.Schema{ + Type: []string{"string"}, + Format: "duration", + Description: "Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s.", + }), + base.CreateSchemaProxy(&base.Schema{ + Type: []string{"number"}, + Format: "float", + Description: "Fractional number of seconds, such as 2 or 4.5.", + }), + }, + Description: "Duration in humand-readable or numeric format.", + }) +} + func stringSchemaWithConstValue(value string) *base.SchemaProxy { node := &yaml.Node{Kind: yaml.ScalarNode, Value: value} return base.CreateSchemaProxy(&base.Schema{ diff --git a/web/api/v1/openapi_paths.go b/web/api/v1/openapi_paths.go index 2f5ab592f7..45db56912c 100644 --- a/web/api/v1/openapi_paths.go +++ b/web/api/v1/openapi_paths.go @@ -30,8 +30,8 @@ func (*OpenAPIBuilder) queryPath() *v3.PathItem { queryParamWithExample("limit", "The maximum number of metrics to return.", false, integerSchema(), []example{{"example", 100}}), queryParamWithExample("time", "The evaluation timestamp (optional, defaults to current time).", false, timestampSchema(), timestampExamples(exampleTime)), queryParamWithExample("query", "The PromQL query to execute.", true, stringSchema(), []example{{"example", "up"}}), - queryParamWithExample("timeout", "Evaluation timeout. Optional. Defaults to and is capped by the value of the -query.timeout flag.", false, stringSchema(), []example{{"example", "30s"}}), - queryParamWithExample("lookback_delta", "Override the lookback period for this query. Optional.", false, stringSchema(), []example{{"example", "5m"}}), + queryParamWithExample("timeout", "Evaluation timeout. Optional. Defaults to and is capped by the value of the -query.timeout flag.", false, durationSchema(), []example{{"example", "30s"}}), + queryParamWithExample("lookback_delta", "Override the lookback period for this query. Optional.", false, durationSchema(), []example{{"example", "5m"}}), queryParamWithExample("stats", "When provided, include query statistics in the response. The special value 'all' enables more comprehensive statistics.", false, stringSchema(), []example{{"example", "all"}}), } return &v3.PathItem{ @@ -57,10 +57,10 @@ func (*OpenAPIBuilder) queryRangePath() *v3.PathItem { queryParamWithExample("limit", "The maximum number of metrics to return.", false, integerSchema(), []example{{"example", 100}}), queryParamWithExample("start", "The start time of the query.", true, timestampSchema(), timestampExamples(exampleTime.Add(-1*time.Hour))), queryParamWithExample("end", "The end time of the query.", true, timestampSchema(), timestampExamples(exampleTime)), - queryParamWithExample("step", "The step size of the query.", true, stringSchema(), []example{{"example", "15s"}}), + queryParamWithExample("step", "The step size of the query.", true, durationSchema(), []example{{"example", "15s"}}), queryParamWithExample("query", "The query to execute.", true, stringSchema(), []example{{"example", "rate(prometheus_http_requests_total{handler=\"/api/v1/query\"}[5m])"}}), - queryParamWithExample("timeout", "Evaluation timeout. Optional. Defaults to and is capped by the value of the -query.timeout flag.", false, stringSchema(), []example{{"example", "30s"}}), - queryParamWithExample("lookback_delta", "Override the lookback period for this query. Optional.", false, stringSchema(), []example{{"example", "5m"}}), + queryParamWithExample("timeout", "Evaluation timeout. Optional. Defaults to and is capped by the value of the -query.timeout flag.", false, durationSchema(), []example{{"example", "30s"}}), + queryParamWithExample("lookback_delta", "Override the lookback period for this query. Optional.", false, durationSchema(), []example{{"example", "5m"}}), queryParamWithExample("stats", "When provided, include query statistics in the response. The special value 'all' enables more comprehensive statistics.", false, stringSchema(), []example{{"example", "all"}}), } return &v3.PathItem{ diff --git a/web/api/v1/testdata/openapi_3.1_golden.yaml b/web/api/v1/testdata/openapi_3.1_golden.yaml index b1514f209d..8c5d028ae5 100644 --- a/web/api/v1/testdata/openapi_3.1_golden.yaml +++ b/web/api/v1/testdata/openapi_3.1_golden.yaml @@ -62,7 +62,14 @@ paths: required: false explode: false schema: - type: string + oneOf: + - type: string + format: duration + description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + - type: number + format: float + description: Fractional number of seconds, such as 2 or 4.5. + description: Duration in humand-readable or numeric format. examples: example: value: 30s @@ -72,7 +79,14 @@ paths: required: false explode: false schema: - type: string + oneOf: + - type: string + format: duration + description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + - type: number + format: float + description: Fractional number of seconds, such as 2 or 4.5. + description: Duration in humand-readable or numeric format. examples: example: value: 5m @@ -248,7 +262,14 @@ paths: required: true explode: false schema: - type: string + oneOf: + - type: string + format: duration + description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + - type: number + format: float + description: Fractional number of seconds, such as 2 or 4.5. + description: Duration in humand-readable or numeric format. examples: example: value: 15s @@ -268,7 +289,14 @@ paths: required: false explode: false schema: - type: string + oneOf: + - type: string + format: duration + description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + - type: number + format: float + description: Fractional number of seconds, such as 2 or 4.5. + description: Duration in humand-readable or numeric format. examples: example: value: 30s @@ -278,7 +306,14 @@ paths: required: false explode: false schema: - type: string + oneOf: + - type: string + format: duration + description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + - type: number + format: float + description: Fractional number of seconds, such as 2 or 4.5. + description: Duration in humand-readable or numeric format. examples: example: value: 5m diff --git a/web/api/v1/testdata/openapi_3.2_golden.yaml b/web/api/v1/testdata/openapi_3.2_golden.yaml index fa79fffecc..944ad1a476 100644 --- a/web/api/v1/testdata/openapi_3.2_golden.yaml +++ b/web/api/v1/testdata/openapi_3.2_golden.yaml @@ -62,7 +62,14 @@ paths: required: false explode: false schema: - type: string + oneOf: + - type: string + format: duration + description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + - type: number + format: float + description: Fractional number of seconds, such as 2 or 4.5. + description: Duration in humand-readable or numeric format. examples: example: value: 30s @@ -72,7 +79,14 @@ paths: required: false explode: false schema: - type: string + oneOf: + - type: string + format: duration + description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + - type: number + format: float + description: Fractional number of seconds, such as 2 or 4.5. + description: Duration in humand-readable or numeric format. examples: example: value: 5m @@ -248,7 +262,14 @@ paths: required: true explode: false schema: - type: string + oneOf: + - type: string + format: duration + description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + - type: number + format: float + description: Fractional number of seconds, such as 2 or 4.5. + description: Duration in humand-readable or numeric format. examples: example: value: 15s @@ -268,7 +289,14 @@ paths: required: false explode: false schema: - type: string + oneOf: + - type: string + format: duration + description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + - type: number + format: float + description: Fractional number of seconds, such as 2 or 4.5. + description: Duration in humand-readable or numeric format. examples: example: value: 30s @@ -278,7 +306,14 @@ paths: required: false explode: false schema: - type: string + oneOf: + - type: string + format: duration + description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + - type: number + format: float + description: Fractional number of seconds, such as 2 or 4.5. + description: Duration in humand-readable or numeric format. examples: example: value: 5m From 8763eef66622a3742586af19e6c175f60a55c8d7 Mon Sep 17 00:00:00 2001 From: Charles Korn Date: Tue, 17 Mar 2026 10:40:56 +1100 Subject: [PATCH 004/170] Address PR feedback: fix typo, move examples, clarify supported duration format Signed-off-by: Charles Korn --- web/api/v1/openapi_helpers.go | 6 +-- web/api/v1/openapi_paths.go | 10 ++-- web/api/v1/testdata/openapi_3.1_golden.yaml | 54 ++++++++++++--------- web/api/v1/testdata/openapi_3.2_golden.yaml | 54 ++++++++++++--------- 4 files changed, 72 insertions(+), 52 deletions(-) diff --git a/web/api/v1/openapi_helpers.go b/web/api/v1/openapi_helpers.go index fd00567194..666310bf0c 100644 --- a/web/api/v1/openapi_helpers.go +++ b/web/api/v1/openapi_helpers.go @@ -174,15 +174,15 @@ func durationSchema() *base.SchemaProxy { base.CreateSchemaProxy(&base.Schema{ Type: []string{"string"}, Format: "duration", - Description: "Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s.", + Description: "Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years).", }), base.CreateSchemaProxy(&base.Schema{ Type: []string{"number"}, Format: "float", - Description: "Fractional number of seconds, such as 2 or 4.5.", + Description: "Fractional number of seconds.", }), }, - Description: "Duration in humand-readable or numeric format.", + Description: "Duration in human-readable or numeric format.", }) } diff --git a/web/api/v1/openapi_paths.go b/web/api/v1/openapi_paths.go index 45db56912c..55d4c1aa59 100644 --- a/web/api/v1/openapi_paths.go +++ b/web/api/v1/openapi_paths.go @@ -30,8 +30,8 @@ func (*OpenAPIBuilder) queryPath() *v3.PathItem { queryParamWithExample("limit", "The maximum number of metrics to return.", false, integerSchema(), []example{{"example", 100}}), queryParamWithExample("time", "The evaluation timestamp (optional, defaults to current time).", false, timestampSchema(), timestampExamples(exampleTime)), queryParamWithExample("query", "The PromQL query to execute.", true, stringSchema(), []example{{"example", "up"}}), - queryParamWithExample("timeout", "Evaluation timeout. Optional. Defaults to and is capped by the value of the -query.timeout flag.", false, durationSchema(), []example{{"example", "30s"}}), - queryParamWithExample("lookback_delta", "Override the lookback period for this query. Optional.", false, durationSchema(), []example{{"example", "5m"}}), + queryParamWithExample("timeout", "Evaluation timeout. Optional. Defaults to and is capped by the value of the -query.timeout flag.", false, durationSchema(), []example{{"duration", "1m30s"}, {"number", "90"}}), + queryParamWithExample("lookback_delta", "Override the lookback period for this query. Optional.", false, durationSchema(), []example{{"duration", "5m"}, {"number", "300"}}), queryParamWithExample("stats", "When provided, include query statistics in the response. The special value 'all' enables more comprehensive statistics.", false, stringSchema(), []example{{"example", "all"}}), } return &v3.PathItem{ @@ -57,10 +57,10 @@ func (*OpenAPIBuilder) queryRangePath() *v3.PathItem { queryParamWithExample("limit", "The maximum number of metrics to return.", false, integerSchema(), []example{{"example", 100}}), queryParamWithExample("start", "The start time of the query.", true, timestampSchema(), timestampExamples(exampleTime.Add(-1*time.Hour))), queryParamWithExample("end", "The end time of the query.", true, timestampSchema(), timestampExamples(exampleTime)), - queryParamWithExample("step", "The step size of the query.", true, durationSchema(), []example{{"example", "15s"}}), + queryParamWithExample("step", "The step size of the query.", true, durationSchema(), []example{{"duration", "15s"}, {"number", "15"}}), queryParamWithExample("query", "The query to execute.", true, stringSchema(), []example{{"example", "rate(prometheus_http_requests_total{handler=\"/api/v1/query\"}[5m])"}}), - queryParamWithExample("timeout", "Evaluation timeout. Optional. Defaults to and is capped by the value of the -query.timeout flag.", false, durationSchema(), []example{{"example", "30s"}}), - queryParamWithExample("lookback_delta", "Override the lookback period for this query. Optional.", false, durationSchema(), []example{{"example", "5m"}}), + queryParamWithExample("timeout", "Evaluation timeout. Optional. Defaults to and is capped by the value of the -query.timeout flag.", false, durationSchema(), []example{{"duration", "1m30s"}, {"number", "90"}}), + queryParamWithExample("lookback_delta", "Override the lookback period for this query. Optional.", false, durationSchema(), []example{{"duration", "5m"}, {"number", "300"}}), queryParamWithExample("stats", "When provided, include query statistics in the response. The special value 'all' enables more comprehensive statistics.", false, stringSchema(), []example{{"example", "all"}}), } return &v3.PathItem{ diff --git a/web/api/v1/testdata/openapi_3.1_golden.yaml b/web/api/v1/testdata/openapi_3.1_golden.yaml index 8c5d028ae5..dce85a7373 100644 --- a/web/api/v1/testdata/openapi_3.1_golden.yaml +++ b/web/api/v1/testdata/openapi_3.1_golden.yaml @@ -65,14 +65,16 @@ paths: oneOf: - type: string format: duration - description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + description: Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years). - type: number format: float - description: Fractional number of seconds, such as 2 or 4.5. - description: Duration in humand-readable or numeric format. + description: Fractional number of seconds. + description: Duration in human-readable or numeric format. examples: - example: - value: 30s + duration: + value: 1m30s + number: + value: "90" - name: lookback_delta in: query description: Override the lookback period for this query. Optional. @@ -82,14 +84,16 @@ paths: oneOf: - type: string format: duration - description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + description: Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years). - type: number format: float - description: Fractional number of seconds, such as 2 or 4.5. - description: Duration in humand-readable or numeric format. + description: Fractional number of seconds. + description: Duration in human-readable or numeric format. examples: - example: + duration: value: 5m + number: + value: "300" - name: stats in: query description: When provided, include query statistics in the response. The special value 'all' enables more comprehensive statistics. @@ -265,14 +269,16 @@ paths: oneOf: - type: string format: duration - description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + description: Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years). - type: number format: float - description: Fractional number of seconds, such as 2 or 4.5. - description: Duration in humand-readable or numeric format. + description: Fractional number of seconds. + description: Duration in human-readable or numeric format. examples: - example: + duration: value: 15s + number: + value: "15" - name: query in: query description: The query to execute. @@ -292,14 +298,16 @@ paths: oneOf: - type: string format: duration - description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + description: Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years). - type: number format: float - description: Fractional number of seconds, such as 2 or 4.5. - description: Duration in humand-readable or numeric format. + description: Fractional number of seconds. + description: Duration in human-readable or numeric format. examples: - example: - value: 30s + duration: + value: 1m30s + number: + value: "90" - name: lookback_delta in: query description: Override the lookback period for this query. Optional. @@ -309,14 +317,16 @@ paths: oneOf: - type: string format: duration - description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + description: Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years). - type: number format: float - description: Fractional number of seconds, such as 2 or 4.5. - description: Duration in humand-readable or numeric format. + description: Fractional number of seconds. + description: Duration in human-readable or numeric format. examples: - example: + duration: value: 5m + number: + value: "300" - name: stats in: query description: When provided, include query statistics in the response. The special value 'all' enables more comprehensive statistics. diff --git a/web/api/v1/testdata/openapi_3.2_golden.yaml b/web/api/v1/testdata/openapi_3.2_golden.yaml index 944ad1a476..3581576735 100644 --- a/web/api/v1/testdata/openapi_3.2_golden.yaml +++ b/web/api/v1/testdata/openapi_3.2_golden.yaml @@ -65,14 +65,16 @@ paths: oneOf: - type: string format: duration - description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + description: Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years). - type: number format: float - description: Fractional number of seconds, such as 2 or 4.5. - description: Duration in humand-readable or numeric format. + description: Fractional number of seconds. + description: Duration in human-readable or numeric format. examples: - example: - value: 30s + duration: + value: 1m30s + number: + value: "90" - name: lookback_delta in: query description: Override the lookback period for this query. Optional. @@ -82,14 +84,16 @@ paths: oneOf: - type: string format: duration - description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + description: Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years). - type: number format: float - description: Fractional number of seconds, such as 2 or 4.5. - description: Duration in humand-readable or numeric format. + description: Fractional number of seconds. + description: Duration in human-readable or numeric format. examples: - example: + duration: value: 5m + number: + value: "300" - name: stats in: query description: When provided, include query statistics in the response. The special value 'all' enables more comprehensive statistics. @@ -265,14 +269,16 @@ paths: oneOf: - type: string format: duration - description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + description: Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years). - type: number format: float - description: Fractional number of seconds, such as 2 or 4.5. - description: Duration in humand-readable or numeric format. + description: Fractional number of seconds. + description: Duration in human-readable or numeric format. examples: - example: + duration: value: 15s + number: + value: "15" - name: query in: query description: The query to execute. @@ -292,14 +298,16 @@ paths: oneOf: - type: string format: duration - description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + description: Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years). - type: number format: float - description: Fractional number of seconds, such as 2 or 4.5. - description: Duration in humand-readable or numeric format. + description: Fractional number of seconds. + description: Duration in human-readable or numeric format. examples: - example: - value: 30s + duration: + value: 1m30s + number: + value: "90" - name: lookback_delta in: query description: Override the lookback period for this query. Optional. @@ -309,14 +317,16 @@ paths: oneOf: - type: string format: duration - description: Human-readable form accepted by Go's time.Duration.ParseDuration(), such as 15s or 2m30s. + description: Human-readable form such as 15s or 2m30s. Supported units are ms (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks) and y (years). - type: number format: float - description: Fractional number of seconds, such as 2 or 4.5. - description: Duration in humand-readable or numeric format. + description: Fractional number of seconds. + description: Duration in human-readable or numeric format. examples: - example: + duration: value: 5m + number: + value: "300" - name: stats in: query description: When provided, include query statistics in the response. The special value 'all' enables more comprehensive statistics. From b2c809b2a54720d562a85e9f1344a3a538c0e340 Mon Sep 17 00:00:00 2001 From: Ridwan Sharif Date: Wed, 22 Apr 2026 20:01:45 +0000 Subject: [PATCH 005/170] scrape: fix staleness tracking for duplicate and out-of-order samples in AppenderV2 Signed-off-by: Ridwan Sharif --- scrape/scrape_append_v2.go | 8 ++++--- scrape/scrape_test.go | 47 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/scrape/scrape_append_v2.go b/scrape/scrape_append_v2.go index 825e56f9df..51863329a2 100644 --- a/scrape/scrape_append_v2.go +++ b/scrape/scrape_append_v2.go @@ -314,6 +314,11 @@ loop: // Append sample to the storage. ref, err = app.Append(ref, lset, st, t, val, h, fh, appOpts) } + if err == nil { + if (parsedTimestamp == nil || sl.trackTimestampsStaleness) && ce != nil { + sl.cache.trackStaleness(ce.ref, ce) + } + } sampleAdded, err = sl.checkAddError(met, exemplars, err, &sampleLimitErr, &bucketLimitErr, &appErrs) if err != nil { if !errors.Is(err, storage.ErrNotFound) { @@ -321,9 +326,6 @@ loop: } break loop } - if (parsedTimestamp == nil || sl.trackTimestampsStaleness) && ce != nil { - sl.cache.trackStaleness(ce.ref, ce) - } // If series wasn't cached (is new, not seen on previous scrape) we need to add it to the scrape cache. // But we only do this for series that were appended to TSDB without errors. diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go index 49ee38f65d..2261f4172b 100644 --- a/scrape/scrape_test.go +++ b/scrape/scrape_test.go @@ -3696,6 +3696,53 @@ func testScrapeLoopAppendGracefullyIfAmendOrOutOfOrderOrOutOfBounds(t *testing.T require.Equal(t, 1, seriesAdded) } +func TestScrapeLoopCreatesStaleMarkersOnAppendFailures(t *testing.T) { + foreachAppendable(t, func(t *testing.T, appV2 bool) { + testScrapeLoopCreatesStaleMarkersOnAppendFailures(t, appV2) + }) +} + +func testScrapeLoopCreatesStaleMarkersOnAppendFailures(t *testing.T, appV2 bool) { + appTest := teststorage.NewAppendable() + sl, _ := newTestScrapeLoop(t, withAppendable(appTest, appV2)) + + now := time.Unix(1, 0) + app := sl.appender() + _, _, _, err := app.append([]byte("metric1 1\n"), "text/plain", now) + require.NoError(t, err) + require.NoError(t, app.Commit()) + + metric1Calls := 0 + appTest.WithErrs(func(ls labels.Labels) error { + switch ls.Get(model.MetricNameLabel) { + case "metric1": + metric1Calls++ + if metric1Calls == 1 { + return storage.ErrOutOfOrderSample + } + return nil + default: + return nil + } + }, nil, nil) + + now2 := time.Unix(2, 0) + app2 := sl.appender() + _, _, _, err = app2.append([]byte("metric1 2\n"), "text/plain", now2) + require.NoError(t, err) + require.NoError(t, app2.Commit()) + + samples := appTest.ResultSamples() + foundStale := false + for _, s := range samples { + if s.L.Get(model.MetricNameLabel) == "metric1" && value.IsStaleNaN(s.V) { + foundStale = true + break + } + } + require.True(t, foundStale, "Stale NaN marker was expected for metric1 but was not found") +} + func TestScrapeLoopOutOfBoundsTimeError(t *testing.T) { foreachAppendable(t, func(t *testing.T, appV2 bool) { testScrapeLoopOutOfBoundsTimeError(t, appV2) From a597d2250aee0ef7ce4fafbcaffa2a330b39cf6f Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Fri, 24 Apr 2026 12:25:09 +0200 Subject: [PATCH 006/170] strutil/subsequence: rank exact matches above non-exact matches Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- util/strutil/subsequence.go | 15 ++++++++--- util/strutil/subsequence_test.go | 45 ++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/util/strutil/subsequence.go b/util/strutil/subsequence.go index 767637e99c..10c8c1e198 100644 --- a/util/strutil/subsequence.go +++ b/util/strutil/subsequence.go @@ -19,6 +19,9 @@ package strutil import "strings" +// Non-exact matches are scaled below 1.0 so rounded scores stay distinguishable from exact matches. +const subsequenceNonExactScoreScale = 0.999 + // SubsequenceMatcher pre-computes the encoding of a fixed search pattern so // that it can be scored against many candidate strings without repeating the // ASCII check or rune conversion on the pattern for every call. The first @@ -52,7 +55,7 @@ func NewSubsequenceMatcher(pattern string) *SubsequenceMatcher { // text in more than one way. // // The raw scoring formula is: Σ(interval_size²) − Σ(gap_size / text_length) − trailing_gap / (2 * text_length). -// The result is normalized by pattern_length² (the maximum possible raw score). +// The result is normalized by pattern_length² and scaled below 1.0 for non-exact matches. func (m *SubsequenceMatcher) Score(text string) float64 { if m.pattern == "" { return 1.0 @@ -184,7 +187,7 @@ func matchSubsequenceString(pattern, text string) float64 { if bestScore < 0 { return 0.0 } - return bestScore / float64(patternLen*patternLen) + return normalizeSubsequenceScore(bestScore, patternLen) } // matchSubsequenceRunes implements the scoring algorithm over pre-converted @@ -267,6 +270,10 @@ func matchSubsequenceRunes(patternSlice, textSlice []rune) float64 { return 0.0 } - // Normalize by pattern_length² (the maximum possible raw score). - return bestScore / float64(patternLen*patternLen) + return normalizeSubsequenceScore(bestScore, patternLen) +} + +func normalizeSubsequenceScore(rawScore float64, patternLen int) float64 { + score := rawScore / float64(patternLen*patternLen) + return score * subsequenceNonExactScoreScale } diff --git a/util/strutil/subsequence_test.go b/util/strutil/subsequence_test.go index 00ac62eca4..bf21914a2d 100644 --- a/util/strutil/subsequence_test.go +++ b/util/strutil/subsequence_test.go @@ -135,28 +135,35 @@ func TestSubsequenceScore(t *testing.T) { name: "prefix match", pattern: "my", text: "my awesome text", - // intervals [0,1], leading=0, trailing=13. raw = 4 - 13/30, normalized by 4. - wantScore: 107.0 / 120.0, + // Intervals [0,1], leading=0, trailing=13. raw = 4 - 13/30, normalized by 4. + wantScore: 107.0 / 120.0 * 0.999, }, { name: "substring match", pattern: "tex", text: "my awesome text", - // intervals [11,13], leading=11, trailing=1. raw = 9 - 11/15 - 1/30, normalized by 9. - wantScore: 247.0 / 270.0, + // Intervals [11,13], leading=11, trailing=1. raw = 9 - 11/15 - 1/30, normalized by 9. + wantScore: 247.0 / 270.0 * 0.999, }, { name: "fuzzy match picks best starting position", pattern: "met", text: "my awesome text", - // intervals [8,9] and [11,11], leading=8, inner gap=1, trailing=3. raw = 5 - 9/15 - 3/30, normalized by 9. - wantScore: 43.0 / 90.0, + // Intervals [8,9] and [11,11], leading=8, inner gap=1, trailing=3. raw = 5 - 9/15 - 3/30, normalized by 9. + wantScore: 43.0 / 90.0 * 0.999, }, { name: "prefers later position with better consecutive run", pattern: "bac", text: "babac", - wantScore: 43.0 / 45.0, // match at [2,4], leading gap=2, trailing=0. raw = 9 - 2/5, normalized by 9. + wantScore: 43.0 / 45.0 * 0.999, // Match at [2,4], leading gap=2, trailing=0. raw = 9 - 2/5, normalized by 9. + }, + { + name: "longer prefix match stays below exact match", + pattern: "handler1", + text: "handler10", + // Intervals [0,7], leading=0, trailing=1. raw = 64 - 1/18, normalized by 64 and scaled. + wantScore: 1149849.0 / 1152000.0, }, { name: "pattern longer than text", @@ -192,8 +199,8 @@ func TestSubsequenceScore(t *testing.T) { name: "unicode prefix match", pattern: "éà", text: "éàü", - // intervals [0,1], leading=0, trailing=1. raw = 4 - 1/6, normalized by 4. - wantScore: 23.0 / 24.0, + // Intervals [0,1], leading=0, trailing=1. raw = 4 - 1/6, normalized by 4. + wantScore: 23.0 / 24.0 * 0.999, }, { name: "unicode no match", @@ -211,16 +218,16 @@ func TestSubsequenceScore(t *testing.T) { name: "unicode fuzzy match with gap between intervals", pattern: "éü", text: "éàü", - // intervals [0,0] and [2,2], leading=0, inner gap=1, trailing=0. - // raw = 1 + 1 - 1/3, normalized by 4. - wantScore: 5.0 / 12.0, + // Intervals [0,0] and [2,2], leading=0, inner gap=1, trailing=0. + // Raw = 1 + 1 - 1/3, normalized by 4. + wantScore: 5.0 / 12.0 * 0.999, }, { name: "mixed ascii and unicode", pattern: "aé", text: "aéb", - // intervals [0,1], leading=0, trailing=1. raw = 4 - 1/6, normalized by 4. - wantScore: 23.0 / 24.0, + // Intervals [0,1], leading=0, trailing=1. raw = 4 - 1/6, normalized by 4. + wantScore: 23.0 / 24.0 * 0.999, }, { name: "unicode chars sharing leading utf-8 byte do not match", @@ -241,18 +248,18 @@ func TestSubsequenceScore(t *testing.T) { pattern: "oa", text: "goat", // 'o'(1),'a'(2) form one interval [1,2], leading gap=1, trailing=1. - // raw = 2² - 1/4 - 1/8 = 29/8, normalized by 2² = 4. - wantScore: 29.0 / 32.0, + // Raw = 2² - 1/4 - 1/8 = 29/8, normalized by 2² = 4. + wantScore: 29.0 / 32.0 * 0.999, }, { name: "repeated chars use greedy match", pattern: "abaa", text: "abbaa", // Matches 'a'(0),'b'(1),'a'(3),'a'(4) as intervals [0,1] and [3,4]. - // raw = 2² + 2² - 1/5, normalized by 4² = 16. + // Raw = 2² + 2² - 1/5, normalized by 4² = 16. // A better match exists at 'a'(0),'b'(2),'a'(3),'a'(4), which would score 49/80, // but this test documents the current greedy behavior. - wantScore: 39.0 / 80.0, + wantScore: 39.0 / 80.0 * 0.999, }, } @@ -271,7 +278,7 @@ func TestSubsequenceScore(t *testing.T) { func TestSubsequenceScoreProperties(t *testing.T) { // Prefix match scores below 1.0; only exact match scores 1.0. // "pro" in "prometheus": intervals [0,2], trailing=7. raw = 9 - 7/20, normalized by 9. - require.InDelta(t, 173.0/180.0, NewSubsequenceMatcher("pro").Score("prometheus"), 1e-9) + require.InDelta(t, 173.0/180.0*0.999, NewSubsequenceMatcher("pro").Score("prometheus"), 1e-9) // Exact match always scores 1.0. require.Equal(t, 1.0, NewSubsequenceMatcher("prometheus").Score("prometheus")) From 327393517041139946b96d03c90252e6f5fe4063 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Mon, 27 Apr 2026 11:57:37 +0200 Subject: [PATCH 007/170] remote: validate snappy decoded length before allocation in read endpoint Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- storage/remote/codec.go | 8 ++++++++ storage/remote/codec_test.go | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/storage/remote/codec.go b/storage/remote/codec.go index c689a51164..dec07dd6bd 100644 --- a/storage/remote/codec.go +++ b/storage/remote/codec.go @@ -67,6 +67,14 @@ func DecodeReadRequest(r *http.Request) (*prompb.ReadRequest, error) { return nil, err } + decodedLen, err := snappy.DecodedLen(compressed) + if err != nil { + return nil, err + } + if decodedLen > decodeReadLimit { + return nil, fmt.Errorf("snappy: decoded length %d exceeds limit %d", decodedLen, decodeReadLimit) + } + reqBuf, err := snappy.Decode(nil, compressed) if err != nil { return nil, err diff --git a/storage/remote/codec_test.go b/storage/remote/codec_test.go index 5da8c8176c..e0f2fe0321 100644 --- a/storage/remote/codec_test.go +++ b/storage/remote/codec_test.go @@ -18,6 +18,7 @@ import ( "errors" "fmt" "io" + "net/http" "sync" "testing" @@ -729,6 +730,17 @@ func TestMergeLabels(t *testing.T) { } } +func TestDecodeReadRequestTooLarge(t *testing.T) { + // 5-byte snappy stream whose header claims 256 MiB decoded length, + // well above decodeReadLimit (32 MiB). + bomb := []byte{0x80, 0x80, 0x80, 0x80, 0x01} + req, err := http.NewRequest(http.MethodPost, "/", bytes.NewReader(bomb)) + require.NoError(t, err) + + _, err = DecodeReadRequest(req) + require.ErrorContains(t, err, "exceeds limit") +} + func TestDecodeWriteRequest(t *testing.T) { buf, _, _, err := buildWriteRequest(nil, writeRequestFixture.Timeseries, nil, nil, nil, nil, "snappy") require.NoError(t, err) From 38f23b9075ced1de2b82d2dad8b2bebb1ecd5b7d Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Wed, 22 Apr 2026 17:31:29 +0200 Subject: [PATCH 008/170] ui: fix stored XSS in old UI heatmap chart tick labels This fixes the stored XSS as described in: https://github.com/prometheus/prometheus/security/advisories/GHSA-fw8g-cg8f-9j28 Signed-off-by: Julius Volz Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- web/ui/react-app/src/pages/graph/Graph.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/ui/react-app/src/pages/graph/Graph.tsx b/web/ui/react-app/src/pages/graph/Graph.tsx index 332b3f4762..4422790cb9 100644 --- a/web/ui/react-app/src/pages/graph/Graph.tsx +++ b/web/ui/react-app/src/pages/graph/Graph.tsx @@ -10,6 +10,7 @@ import { Button } from 'reactstrap'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faTimes } from '@fortawesome/free-solid-svg-icons'; import { GraphDisplayMode } from './Panel'; +import { escapeHTML } from '../../utils'; require('../../vendor/flot/jquery.flot'); require('../../vendor/flot/jquery.flot.stack'); @@ -151,7 +152,7 @@ class Graph extends PureComponent { if (options.yaxis && isHeatmap) { options.yaxis.ticks = () => new Array(data.length + 1).fill(0).map((_el, i) => i); - options.yaxis.tickFormatter = (val) => `${val ? data[val - 1].labels.le : ''}`; + options.yaxis.tickFormatter = (val) => `${val ? escapeHTML(data[val - 1].labels.le) : ''}`; options.yaxis.min = 0; options.yaxis.max = data.length; options.series.lines = { show: false }; From 5ba354575305e087c09a647e8a62e38be01d17c5 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Mon, 27 Apr 2026 15:48:10 +0200 Subject: [PATCH 009/170] Release 3.11.3 Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- CHANGELOG.md | 13 +++++++++++++ VERSION | 2 +- web/ui/mantine-ui/package.json | 4 ++-- web/ui/module/codemirror-promql/package.json | 4 ++-- web/ui/module/lezer-promql/package.json | 2 +- web/ui/package-lock.json | 14 +++++++------- web/ui/package.json | 2 +- 7 files changed, 27 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97cd81d170..821c133eb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 3.11.3 / 2026-04-27 + +This release fixes mutiple security issues. + +We would like to thank the following people for the responsible disclosures: +- Shadowbyte (4c1dr3aper) - Charlie Lewis for the Remote-Read snappy decode vulnerability. +- Brett Gervasoni for the AzureAD OAuth `client_secret` vulnerability. +- @iiihaiii and @Ngocnn97 for the Old UI XSS vulnerability. + +- [SECURITY] AzureAD remote write: Fix OAuth `client_secret` being exposed in plaintext via `/-/config` endpoint. GHSA-wg65-39gg-5wfj / CVE-2026-42151 #18590 +- [SECURITY] Remote-read: Reject snappy-compressed requests whose declared decoded length exceeds the decode limit. GHSA-8rm2-7qqf-34qm / CVE-2026-42154 #18584 +- [SECURITY] UI: Fix stored XSS via unescaped `le` label values in old UI heatmap chart tick labels. GHSA-fw8g-cg8f-9j28 #18588 + ## 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. diff --git a/VERSION b/VERSION index 1e33456831..d2c96c0ab8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.11.2 +3.11.3 diff --git a/web/ui/mantine-ui/package.json b/web/ui/mantine-ui/package.json index 6af3419aca..cae1dc41f0 100644 --- a/web/ui/mantine-ui/package.json +++ b/web/ui/mantine-ui/package.json @@ -1,7 +1,7 @@ { "name": "@prometheus-io/mantine-ui", "private": true, - "version": "0.311.2", + "version": "0.311.3", "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.2", + "@prometheus-io/codemirror-promql": "0.311.3", "@reduxjs/toolkit": "^2.11.2", "@tabler/icons-react": "^3.40.0", "@tanstack/react-query": "^5.95.2", diff --git a/web/ui/module/codemirror-promql/package.json b/web/ui/module/codemirror-promql/package.json index 8f12a5c31e..32b9e7fd2d 100644 --- a/web/ui/module/codemirror-promql/package.json +++ b/web/ui/module/codemirror-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/codemirror-promql", - "version": "0.311.2", + "version": "0.311.3", "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.2", + "@prometheus-io/lezer-promql": "0.311.3", "lru-cache": "^11.2.7" }, "devDependencies": { diff --git a/web/ui/module/lezer-promql/package.json b/web/ui/module/lezer-promql/package.json index 23818f2bba..d3f93ff577 100644 --- a/web/ui/module/lezer-promql/package.json +++ b/web/ui/module/lezer-promql/package.json @@ -1,6 +1,6 @@ { "name": "@prometheus-io/lezer-promql", - "version": "0.311.2", + "version": "0.311.3", "description": "lezer-based PromQL grammar", "main": "dist/index.cjs", "type": "module", diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index d171bc249f..2746578217 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -1,12 +1,12 @@ { "name": "prometheus-io", - "version": "0.311.2", + "version": "0.311.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "prometheus-io", - "version": "0.311.2", + "version": "0.311.3", "workspaces": [ "mantine-ui", "module/*" @@ -24,7 +24,7 @@ }, "mantine-ui": { "name": "@prometheus-io/mantine-ui", - "version": "0.311.2", + "version": "0.311.3", "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.2", + "@prometheus-io/codemirror-promql": "0.311.3", "@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.2", + "version": "0.311.3", "license": "Apache-2.0", "dependencies": { - "@prometheus-io/lezer-promql": "0.311.2", + "@prometheus-io/lezer-promql": "0.311.3", "lru-cache": "^11.2.7" }, "devDependencies": { @@ -205,7 +205,7 @@ }, "module/lezer-promql": { "name": "@prometheus-io/lezer-promql", - "version": "0.311.2", + "version": "0.311.3", "license": "Apache-2.0", "devDependencies": { "@lezer/generator": "^1.8.0", diff --git a/web/ui/package.json b/web/ui/package.json index cad35c9697..2dbe4cf049 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -1,7 +1,7 @@ { "name": "prometheus-io", "description": "Monorepo for the Prometheus UI", - "version": "0.311.2", + "version": "0.311.3", "private": true, "scripts": { "build": "bash build_ui.sh --all", From 9f2022e6f64cd68dd0f37210d4f4099679076188 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Mon, 27 Apr 2026 16:26:31 +0200 Subject: [PATCH 010/170] rules: fix flaky TestDependencyMapUpdatesOnGroupUpdate The test called ruleManager.start() before ruleManager.Update(), so the group goroutine skipped the <-m.block wait and began evaluating immediately. The fixture has a recording rule, and if the first 10s tick fired before defer ruleManager.Stop() ran, Eval was called with a nil QueryFunc (and nil Appendable), causing a nil pointer dereference. Fix by providing Appendable, Queryable, and QueryFunc in the ManagerOptions, matching the pattern used by other tests that load real rule files and start the manager. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- rules/manager_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/rules/manager_test.go b/rules/manager_test.go index f0dfcf26f4..2da6aa624c 100644 --- a/rules/manager_test.go +++ b/rules/manager_test.go @@ -1946,10 +1946,16 @@ func TestDependentRulesWithNonMetricExpression(t *testing.T) { } func TestDependencyMapUpdatesOnGroupUpdate(t *testing.T) { + storage := teststorage.New(t) + engine := testEngine(t) + files := []string{"fixtures/rules.yaml"} ruleManager := NewManager(&ManagerOptions{ - Context: context.Background(), - Logger: promslog.NewNopLogger(), + Appendable: storage, + Queryable: storage, + QueryFunc: EngineQueryFunc(engine, storage), + Context: context.Background(), + Logger: promslog.NewNopLogger(), }) ruleManager.start() From fcdaef1365027c152221a788db079d7391a8cc57 Mon Sep 17 00:00:00 2001 From: Rich Date: Thu, 27 Feb 2025 16:44:46 +0000 Subject: [PATCH 011/170] Use a default IPv6 address for IPv6 only instances Signed-off-by: Rich --- discovery/aws/ec2.go | 97 ++++++++++++++++++++--------- discovery/aws/ec2_test.go | 66 +++++++++++++++++++- docs/configuration/configuration.md | 2 + 3 files changed, 133 insertions(+), 32 deletions(-) diff --git a/discovery/aws/ec2.go b/discovery/aws/ec2.go index deefa52e9c..364ec4f102 100644 --- a/discovery/aws/ec2.go +++ b/discovery/aws/ec2.go @@ -55,6 +55,7 @@ const ( ec2LabelInstanceType = ec2Label + "instance_type" ec2LabelOwnerID = ec2Label + "owner_id" ec2LabelPlatform = ec2Label + "platform" + ec2LabelDefaultIPv6Address = ec2Label + "default_ipv6_address" ec2LabelPrimaryIPv6Addresses = ec2Label + "primary_ipv6_addresses" ec2LabelPrimarySubnetID = ec2Label + "primary_subnet_id" ec2LabelPrivateDNS = ec2Label + "private_dns_name" @@ -306,7 +307,9 @@ func (d *EC2Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error for _, r := range p.Reservations { for _, inst := range r.Instances { - if inst.PrivateIpAddress == nil { + defaultIPv6Addr, primaryIPv6Addrs, ipv6Addrs := getInstanceIPv6Addresses(&inst) + + if inst.PrivateIpAddress == nil && defaultIPv6Addr == nil { continue } @@ -319,12 +322,20 @@ func (d *EC2Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error labels[ec2LabelOwnerID] = model.LabelValue(*r.OwnerId) } - labels[ec2LabelPrivateIP] = model.LabelValue(*inst.PrivateIpAddress) + if defaultIPv6Addr != nil { + labels[ec2LabelDefaultIPv6Address] = model.LabelValue(*defaultIPv6Addr) + } + + if inst.PrivateIpAddress != nil { + labels[ec2LabelPrivateIP] = model.LabelValue(*inst.PrivateIpAddress) + labels[model.AddressLabel] = model.LabelValue(net.JoinHostPort(*inst.PrivateIpAddress, strconv.Itoa(d.cfg.Port))) + } else { + labels[model.AddressLabel] = model.LabelValue(net.JoinHostPort(*defaultIPv6Addr, strconv.Itoa(d.cfg.Port))) + } + if inst.PrivateDnsName != nil { labels[ec2LabelPrivateDNS] = model.LabelValue(*inst.PrivateDnsName) } - addr := net.JoinHostPort(*inst.PrivateIpAddress, strconv.Itoa(d.cfg.Port)) - labels[model.AddressLabel] = model.LabelValue(addr) if inst.Platform != "" { labels[ec2LabelPlatform] = model.LabelValue(inst.Platform) @@ -334,6 +345,21 @@ func (d *EC2Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error labels[ec2LabelPublicIP] = model.LabelValue(*inst.PublicIpAddress) labels[ec2LabelPublicDNS] = model.LabelValue(*inst.PublicDnsName) } + + if primaryIPv6Addrs != nil { + labels[ec2LabelPrimaryIPv6Addresses] = model.LabelValue( + ec2LabelSeparator + + strings.Join(primaryIPv6Addrs, ec2LabelSeparator) + + ec2LabelSeparator) + } + + if ipv6Addrs != nil { + labels[ec2LabelIPv6Addresses] = model.LabelValue( + ec2LabelSeparator + + strings.Join(ipv6Addrs, ec2LabelSeparator) + + ec2LabelSeparator) + } + labels[ec2LabelAMI] = model.LabelValue(*inst.ImageId) labels[ec2LabelAZ] = model.LabelValue(*inst.Placement.AvailabilityZone) azID, ok := d.azToAZID[*inst.Placement.AvailabilityZone] @@ -359,8 +385,6 @@ func (d *EC2Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error labels[ec2LabelPrimarySubnetID] = model.LabelValue(*inst.SubnetId) var subnets []string - var ipv6addrs []string - var primaryipv6addrs []string subnetsMap := make(map[string]struct{}) for _, eni := range inst.NetworkInterfaces { if eni.SubnetId == nil { @@ -371,36 +395,11 @@ func (d *EC2Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error subnetsMap[*eni.SubnetId] = struct{}{} subnets = append(subnets, *eni.SubnetId) } - - for _, ipv6addr := range eni.Ipv6Addresses { - ipv6addrs = append(ipv6addrs, *ipv6addr.Ipv6Address) - if *ipv6addr.IsPrimaryIpv6 { - // we might have to extend the slice with more than one element - // that could leave empty strings in the list which is intentional - // to keep the position/device index information - for int32(len(primaryipv6addrs)) <= *eni.Attachment.DeviceIndex { - primaryipv6addrs = append(primaryipv6addrs, "") - } - primaryipv6addrs[*eni.Attachment.DeviceIndex] = *ipv6addr.Ipv6Address - } - } } labels[ec2LabelSubnetID] = model.LabelValue( ec2LabelSeparator + strings.Join(subnets, ec2LabelSeparator) + ec2LabelSeparator) - if len(ipv6addrs) > 0 { - labels[ec2LabelIPv6Addresses] = model.LabelValue( - ec2LabelSeparator + - strings.Join(ipv6addrs, ec2LabelSeparator) + - ec2LabelSeparator) - } - if len(primaryipv6addrs) > 0 { - labels[ec2LabelPrimaryIPv6Addresses] = model.LabelValue( - ec2LabelSeparator + - strings.Join(primaryipv6addrs, ec2LabelSeparator) + - ec2LabelSeparator) - } } for _, t := range inst.Tags { @@ -417,3 +416,39 @@ func (d *EC2Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error return []*targetgroup.Group{tg}, nil } + +func getInstanceIPv6Addresses(i *ec2Types.Instance) (*string, []string, []string) { + var primaryIPv6Addrs []string + var ipv6Addrs []string + + if i.VpcId != nil { + for _, eni := range i.NetworkInterfaces { + if eni.SubnetId == nil { + continue + } + + for _, ipv6addr := range eni.Ipv6Addresses { + ipv6Addrs = append(ipv6Addrs, *ipv6addr.Ipv6Address) + if *ipv6addr.IsPrimaryIpv6 { + // we might have to extend the slice with more than one element + // that could leave empty strings in the list which is intentional + // to keep the position/device index information + for int32(len(primaryIPv6Addrs)) <= *eni.Attachment.DeviceIndex { + primaryIPv6Addrs = append(primaryIPv6Addrs, "") + } + primaryIPv6Addrs[*eni.Attachment.DeviceIndex] = *ipv6addr.Ipv6Address + } + } + } + + // Find an IPv6 address we can use by default. Pick the first primary one if + // there is any available, if not then pick the first non-primary address. + for _, ipv6addr := range append(primaryIPv6Addrs, ipv6Addrs...) { + if ipv6addr != "" { + return &ipv6addr, primaryIPv6Addrs, ipv6Addrs + } + } + } + + return nil, primaryIPv6Addrs, ipv6Addrs +} diff --git a/discovery/aws/ec2_test.go b/discovery/aws/ec2_test.go index bd1047ffc0..b6899c1a65 100644 --- a/discovery/aws/ec2_test.go +++ b/discovery/aws/ec2_test.go @@ -108,7 +108,7 @@ func TestEC2DiscoveryRefresh(t *testing.T) { expected []*targetgroup.Group }{ { - name: "NoPrivateIp", + name: "NoPrivateIpOrIpv6", ec2Data: &ec2DataStore{ region: "region-noprivateip", azToAZID: map[string]string{ @@ -351,6 +351,7 @@ func TestEC2DiscoveryRefresh(t *testing.T) { "__meta_ec2_instance_type": model.LabelValue("instance-type-ipv6"), "__meta_ec2_ipv6_addresses": model.LabelValue(",2001:db8:2::1:1,2001:db8:2::2:1,2001:db8:2::2:2,2001:db8:2::3:1,"), "__meta_ec2_owner_id": model.LabelValue(""), + "__meta_ec2_default_ipv6_address": model.LabelValue("2001:db8:2::2:2"), "__meta_ec2_primary_ipv6_addresses": model.LabelValue(",,2001:db8:2::2:2,,2001:db8:2::3:1,"), "__meta_ec2_primary_subnet_id": model.LabelValue("azid-2"), "__meta_ec2_private_ip": model.LabelValue("9.10.11.12"), @@ -362,6 +363,69 @@ func TestEC2DiscoveryRefresh(t *testing.T) { }, }, }, + { + name: "Ipv6-Only", + ec2Data: &ec2DataStore{ + region: "region-ipv6-only", + azToAZID: map[string]string{ + "azname-a": "azid-1", + "azname-b": "azid-2", + "azname-c": "azid-3", + }, + + instances: []ec2Types.Instance{ + { + // just the minimum needed for the refresh work + ImageId: strptr("ami-ipv6-only"), + InstanceId: strptr("instance-id-ipv6-only"), + InstanceType: "instance-type-ipv6-only", + Placement: &ec2Types.Placement{AvailabilityZone: strptr("azname-b")}, + State: &ec2Types.InstanceState{Name: "running"}, + SubnetId: strptr("azid-2"), + VpcId: strptr("vpc-ipv6-only"), + // network interfaces + NetworkInterfaces: []ec2Types.InstanceNetworkInterface{ + // interface without primary IPv6, index 0 + { + Attachment: &ec2Types.InstanceNetworkInterfaceAttachment{ + DeviceIndex: aws.Int32(0), + }, + Ipv6Addresses: []ec2Types.InstanceIpv6Address{ + { + Ipv6Address: strptr("2001:db8:2::1:1"), + IsPrimaryIpv6: boolptr(false), + }, + }, + SubnetId: strptr("azid-2"), + }, + }, + }, + }, + }, + expected: []*targetgroup.Group{ + { + Source: "region-ipv6-only", + Targets: []model.LabelSet{ + { + "__address__": model.LabelValue("[2001:db8:2::1:1]:4242"), + "__meta_ec2_ami": model.LabelValue("ami-ipv6-only"), + "__meta_ec2_availability_zone": model.LabelValue("azname-b"), + "__meta_ec2_availability_zone_id": model.LabelValue("azid-2"), + "__meta_ec2_instance_id": model.LabelValue("instance-id-ipv6-only"), + "__meta_ec2_instance_state": model.LabelValue("running"), + "__meta_ec2_instance_type": model.LabelValue("instance-type-ipv6-only"), + "__meta_ec2_ipv6_addresses": model.LabelValue(",2001:db8:2::1:1,"), + "__meta_ec2_owner_id": model.LabelValue(""), + "__meta_ec2_default_ipv6_address": model.LabelValue("2001:db8:2::1:1"), + "__meta_ec2_primary_subnet_id": model.LabelValue("azid-2"), + "__meta_ec2_region": model.LabelValue("region-ipv6-only"), + "__meta_ec2_subnet_id": model.LabelValue(",azid-2,"), + "__meta_ec2_vpc_id": model.LabelValue("vpc-ipv6-only"), + }, + }, + }, + }, + }, } { t.Run(tt.name, func(t *testing.T) { client := newMockEC2Client(tt.ec2Data) diff --git a/docs/configuration/configuration.md b/docs/configuration/configuration.md index 70a6a693c8..ee35704cf5 100644 --- a/docs/configuration/configuration.md +++ b/docs/configuration/configuration.md @@ -902,6 +902,7 @@ The following meta labels are available on targets during [relabeling](#relabel_ * `__meta_ec2_ipv6_addresses`: comma separated list of IPv6 addresses assigned to the instance's network interfaces, if present * `__meta_ec2_owner_id`: the ID of the AWS account that owns the EC2 instance * `__meta_ec2_platform`: the Operating System platform, set to 'windows' on Windows servers, absent otherwise +* `__meta_ec2_default_ipv6_address`: the first primary IPv6 address found if present, otherwise first non-primary IPv6 address, if present * `__meta_ec2_primary_ipv6_addresses`: comma separated list of the Primary IPv6 addresses of the instance, if present. The list is ordered based on the position of each corresponding network interface in the attachment order. * `__meta_ec2_primary_subnet_id`: the subnet ID of the primary network interface, if available * `__meta_ec2_private_dns_name`: the private DNS name of the instance, if available @@ -1832,6 +1833,7 @@ The following meta labels are available on targets during [relabeling](#relabel_ * `__meta_ec2_ipv6_addresses`: comma separated list of IPv6 addresses assigned to the instance's network interfaces, if present * `__meta_ec2_owner_id`: the ID of the AWS account that owns the EC2 instance * `__meta_ec2_platform`: the Operating System platform, set to 'windows' on Windows servers, absent otherwise +* `__meta_ec2_default_ipv6_address`: the first primary IPv6 address found if present, otherwise first non-primary IPv6 address, if present * `__meta_ec2_primary_ipv6_addresses`: comma separated list of the Primary IPv6 addresses of the instance, if present. The list is ordered based on the position of each corresponding network interface in the attachment order. * `__meta_ec2_primary_subnet_id`: the subnet ID of the primary network interface, if available * `__meta_ec2_private_dns_name`: the private DNS name of the instance, if available From 6fc7f37c7a1973a1559eb9c91687fa6069647895 Mon Sep 17 00:00:00 2001 From: Filip Boye-Kofi Date: Sun, 3 May 2026 10:34:35 +0200 Subject: [PATCH 012/170] refactor: simplify of calling functions Signed-off-by: Filip Boye-Kofi --- util/fmtutil/format.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/fmtutil/format.go b/util/fmtutil/format.go index a4ac7d43ca..560626d206 100644 --- a/util/fmtutil/format.go +++ b/util/fmtutil/format.go @@ -108,7 +108,7 @@ func makeTimeseries(wr *prompb.WriteRequest, labels map[string]string, m *dto.Me timestamp := m.GetTimestampMs() if timestamp == 0 { - timestamp = time.Now().UnixNano() / int64(time.Millisecond) + timestamp = time.Now().UnixMilli() } switch { From 4a7c1391aeaf6d5bab41e43fd8bc7c42f0387f5c Mon Sep 17 00:00:00 2001 From: Ridwan Sharif Date: Sun, 3 May 2026 19:05:24 +0000 Subject: [PATCH 013/170] test: rename stale marker test to TestScrapeLoopCreatesStaleMarkersOnOOOAppend and simulate OOO errors Signed-off-by: Ridwan Sharif --- scrape/scrape_test.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scrape/scrape_test.go b/scrape/scrape_test.go index 2261f4172b..5bc47133ad 100644 --- a/scrape/scrape_test.go +++ b/scrape/scrape_test.go @@ -3696,13 +3696,13 @@ func testScrapeLoopAppendGracefullyIfAmendOrOutOfOrderOrOutOfBounds(t *testing.T require.Equal(t, 1, seriesAdded) } -func TestScrapeLoopCreatesStaleMarkersOnAppendFailures(t *testing.T) { +func TestScrapeLoopCreatesStaleMarkersOnOOOAppend(t *testing.T) { foreachAppendable(t, func(t *testing.T, appV2 bool) { - testScrapeLoopCreatesStaleMarkersOnAppendFailures(t, appV2) + testScrapeLoopCreatesStaleMarkersOnOOOAppend(t, appV2) }) } -func testScrapeLoopCreatesStaleMarkersOnAppendFailures(t *testing.T, appV2 bool) { +func testScrapeLoopCreatesStaleMarkersOnOOOAppend(t *testing.T, appV2 bool) { appTest := teststorage.NewAppendable() sl, _ := newTestScrapeLoop(t, withAppendable(appTest, appV2)) @@ -3713,10 +3713,14 @@ func testScrapeLoopCreatesStaleMarkersOnAppendFailures(t *testing.T, appV2 bool) require.NoError(t, app.Commit()) metric1Calls := 0 + // The test storage doesn't track order, so it cannot generate OOO error, + // we have to emulate it. appTest.WithErrs(func(ls labels.Labels) error { switch ls.Get(model.MetricNameLabel) { case "metric1": metric1Calls++ + // Only return error on the first append, the second one will be the + // staleness marker. if metric1Calls == 1 { return storage.ErrOutOfOrderSample } From cdf018441947bf028d9ae5a4f0da8bade38842e3 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Mon, 4 May 2026 15:14:31 +0200 Subject: [PATCH 014/170] Promote auto-reload-config stable Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- cmd/prometheus/main.go | 19 +++++++++++++------ cmd/prometheus/reload_test.go | 2 +- docs/command-line/prometheus.md | 5 +++-- docs/feature_flags.md | 13 ------------- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/cmd/prometheus/main.go b/cmd/prometheus/main.go index c731c95ed1..409b72f5f9 100644 --- a/cmd/prometheus/main.go +++ b/cmd/prometheus/main.go @@ -252,10 +252,7 @@ func (c *flagConfig) setFeatureListOptions(logger *slog.Logger) error { logger.Info("Experimental per-step statistics reporting") case "auto-reload-config": c.enableAutoReload = true - if s := time.Duration(c.autoReloadInterval).Seconds(); s > 0 && s < 1 { - c.autoReloadInterval, _ = model.ParseDuration("1s") - } - logger.Info("Enabled automatic configuration file reloading. Checking for configuration changes every", "interval", c.autoReloadInterval) + logger.Warn("This option for --enable-feature is deprecated. Use --config.auto-reload instead.", "option", o) case "concurrent-rule-eval": c.enableConcurrentRuleEval = true logger.Info("Experimental concurrent rule evaluation enabled.") @@ -398,7 +395,10 @@ func main() { a.Flag("config.file", "Prometheus configuration file path."). Default("prometheus.yml").StringVar(&cfg.configFile) - a.Flag("config.auto-reload-interval", "Specifies the interval for checking and automatically reloading the Prometheus configuration file upon detecting changes."). + a.Flag("config.auto-reload", "Enable automatic configuration file reloading. See also --config.auto-reload-interval."). + Default("false").BoolVar(&cfg.enableAutoReload) + + a.Flag("config.auto-reload-interval", "Specifies the interval for checking and automatically reloading the Prometheus configuration file upon detecting changes. Only used when --config.auto-reload is set."). Default("30s").SetValue(&cfg.autoReloadInterval) a.Flag("web.listen-address", "Address to listen on for UI, API, and telemetry. Can be repeated."). @@ -619,7 +619,7 @@ func main() { a.Flag("scrape.discovery-reload-interval", "Interval used by scrape manager to throttle target groups updates."). Hidden().Default("5s").SetValue(&cfg.scrape.DiscoveryReloadInterval) - a.Flag("enable-feature", "Comma separated feature names to enable. Valid options: auto-reload-config, concurrent-rule-eval, created-timestamp-zero-ingestion, delayed-compaction, exemplar-storage, extra-scrape-metrics, memory-snapshot-on-shutdown, metadata-wal-records, old-ui, otlp-deltatocumulative, otlp-native-delta-ingestion, promql-binop-fill-modifiers, promql-delayed-name-removal, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, st-storage, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details."). + a.Flag("enable-feature", "Comma separated feature names to enable. Valid options: concurrent-rule-eval, created-timestamp-zero-ingestion, delayed-compaction, exemplar-storage, extra-scrape-metrics, memory-snapshot-on-shutdown, metadata-wal-records, old-ui, otlp-deltatocumulative, otlp-native-delta-ingestion, promql-binop-fill-modifiers, promql-delayed-name-removal, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, st-storage, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details."). StringsVar(&cfg.featureList) a.Flag("agent", "Run Prometheus in 'Agent mode'.").BoolVar(&agentMode) @@ -655,6 +655,13 @@ func main() { os.Exit(1) } + if cfg.enableAutoReload { + if s := time.Duration(cfg.autoReloadInterval).Seconds(); s < 1 { + cfg.autoReloadInterval, _ = model.ParseDuration("1s") + } + logger.Info("Automatic configuration file reloading enabled", "interval", cfg.autoReloadInterval) + } + promqlParser := parser.NewParser(cfg.parserOpts) if agentMode && len(serverOnlyFlags) > 0 { diff --git a/cmd/prometheus/reload_test.go b/cmd/prometheus/reload_test.go index 2841e23b36..1a75b410cf 100644 --- a/cmd/prometheus/reload_test.go +++ b/cmd/prometheus/reload_test.go @@ -119,7 +119,7 @@ func runTestSteps(t *testing.T, steps []struct { require.NoError(t, os.WriteFile(configFilePath, []byte(steps[0].configText), 0o644), "Failed to write initial config file") port := testutil.RandomUnprivilegedPort(t) - prom := prometheusCommandWithLogging(t, configFilePath, port, "--enable-feature=auto-reload-config", "--config.auto-reload-interval=1s") + prom := prometheusCommandWithLogging(t, configFilePath, port, "--config.auto-reload", "--config.auto-reload-interval=1s") require.NoError(t, prom.Start()) baseURL := "http://localhost:" + strconv.Itoa(port) diff --git a/docs/command-line/prometheus.md b/docs/command-line/prometheus.md index 77e519ff94..e21c4c2a67 100644 --- a/docs/command-line/prometheus.md +++ b/docs/command-line/prometheus.md @@ -12,7 +12,8 @@ The Prometheus monitoring server | -h, --help | Show context-sensitive help (also try --help-long and --help-man). | | | --version | Show application version. | | | --config.file | Prometheus configuration file path. | `prometheus.yml` | -| --config.auto-reload-interval | Specifies the interval for checking and automatically reloading the Prometheus configuration file upon detecting changes. | `30s` | +| --config.auto-reload | Enable automatic configuration file reloading. See also --config.auto-reload-interval. | `false` | +| --config.auto-reload-interval | Specifies the interval for checking and automatically reloading the Prometheus configuration file upon detecting changes. Only used when --config.auto-reload is set. | `30s` | | --web.listen-address ... | Address to listen on for UI, API, and telemetry. Can be repeated. | `0.0.0.0:9090` | | --auto-gomaxprocs | Automatically set GOMAXPROCS to match Linux container CPU quota | `true` | | --auto-gomemlimit | Automatically set GOMEMLIMIT to match Linux container or system memory limit | `true` | @@ -61,7 +62,7 @@ The Prometheus monitoring server | --query.timeout | Maximum time a query may take before being aborted. Use with server mode only. | `2m` | | --query.max-concurrency | Maximum number of queries executed concurrently. Use with server mode only. | `20` | | --query.max-samples | Maximum number of samples a single query can load into memory. Note that queries will fail if they try to load more samples than this into memory, so this also limits the number of samples a query can return. Use with server mode only. | `50000000` | -| --enable-feature ... | Comma separated feature names to enable. Valid options: auto-reload-config, concurrent-rule-eval, created-timestamp-zero-ingestion, delayed-compaction, exemplar-storage, extra-scrape-metrics, memory-snapshot-on-shutdown, metadata-wal-records, old-ui, otlp-deltatocumulative, otlp-native-delta-ingestion, promql-binop-fill-modifiers, promql-delayed-name-removal, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, st-storage, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details. | | +| --enable-feature ... | Comma separated feature names to enable. Valid options: concurrent-rule-eval, created-timestamp-zero-ingestion, delayed-compaction, exemplar-storage, extra-scrape-metrics, memory-snapshot-on-shutdown, metadata-wal-records, old-ui, otlp-deltatocumulative, otlp-native-delta-ingestion, promql-binop-fill-modifiers, promql-delayed-name-removal, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, st-storage, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details. | | | --agent | Run Prometheus in 'Agent mode'. | | | --log.level | Only log messages with the given severity or above. One of: [debug, info, warn, error] | `info` | | --log.format | Output format of log messages. One of: [logfmt, json] | `logfmt` | diff --git a/docs/feature_flags.md b/docs/feature_flags.md index 0538e9ca48..fddb4dcf6b 100644 --- a/docs/feature_flags.md +++ b/docs/feature_flags.md @@ -170,19 +170,6 @@ fixes the possible problem with the feature flag.) It is possible to craft a query that aggregates by `__name__` and puts samples with and without delayed name removal into the same group. In that case, the name is removed from the affected group. Note that this case hardly occurs in queries that fulfill a practical purpose. -## Auto Reload Config - -`--enable-feature=auto-reload-config` - -When enabled, Prometheus will automatically reload its configuration file at a -specified interval. The interval is defined by the -`--config.auto-reload-interval` flag, which defaults to `30s`. - -Configuration reloads are triggered by detecting changes in the checksum of the -main configuration file or any referenced files, such as rule and scrape -configurations. To ensure consistency and avoid issues during reloads, it's -recommended to update these files atomically. - ## OTLP Delta Conversion `--enable-feature=otlp-deltatocumulative` From 20b5f16159062b8258f6c15022de3cea5f87bb29 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 6 May 2026 12:10:03 +0200 Subject: [PATCH 015/170] web/api: emit duration expression trees Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- web/api/v1/translate_ast.go | 41 +++++++ web/api/v1/translate_ast_test.go | 199 +++++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+) create mode 100644 web/api/v1/translate_ast_test.go diff --git a/web/api/v1/translate_ast.go b/web/api/v1/translate_ast.go index 3c2bc09943..dc2b0166f8 100644 --- a/web/api/v1/translate_ast.go +++ b/web/api/v1/translate_ast.go @@ -84,7 +84,9 @@ func translateAST(node parser.Expr) any { "type": "matrixSelector", "name": vs.Name, "range": n.Range.Milliseconds(), + "rangeExpr": translateDurationExpr(n.RangeExpr), "offset": vs.OriginalOffset.Milliseconds(), + "offsetExpr": translateDurationExpr(vs.OriginalOffsetExpr), "matchers": translateMatchers(vs.LabelMatchers), "timestamp": vs.Timestamp, "startOrEnd": getStartOrEnd(vs.StartOrEnd), @@ -96,11 +98,16 @@ func translateAST(node parser.Expr) any { "type": "subquery", "expr": translateAST(n.Expr), "range": n.Range.Milliseconds(), + "rangeExpr": translateDurationExpr(n.RangeExpr), "offset": n.OriginalOffset.Milliseconds(), + "offsetExpr": translateDurationExpr(n.OriginalOffsetExpr), "step": n.Step.Milliseconds(), + "stepExpr": translateDurationExpr(n.StepExpr), "timestamp": n.Timestamp, "startOrEnd": getStartOrEnd(n.StartOrEnd), } + case *parser.DurationExpr: + return translateDurationExpr(n) case *parser.NumberLiteral: return map[string]string{ "type": "numberLiteral", @@ -127,6 +134,7 @@ func translateAST(node parser.Expr) any { "type": "vectorSelector", "name": n.Name, "offset": n.OriginalOffset.Milliseconds(), + "offsetExpr": translateDurationExpr(n.OriginalOffsetExpr), "matchers": translateMatchers(n.LabelMatchers), "timestamp": n.Timestamp, "startOrEnd": getStartOrEnd(n.StartOrEnd), @@ -137,6 +145,39 @@ func translateAST(node parser.Expr) any { panic("unsupported node type") } +func translateDurationExpr(node parser.Expr) any { + if node == nil { + return nil + } + + switch n := node.(type) { + case *parser.DurationExpr: + if n == nil { + return nil + } + + return map[string]any{ + "type": "durationExpr", + "op": n.Op.String(), + "lhs": translateDurationExpr(n.LHS), + "rhs": translateDurationExpr(n.RHS), + "wrapped": n.Wrapped, + } + case *parser.NumberLiteral: + if n == nil { + return nil + } + + return map[string]any{ + "type": "numberLiteral", + "val": strconv.FormatFloat(n.Val, 'f', -1, 64), + "duration": n.Duration, + } + default: + return translateAST(n) + } +} + func sanitizeList(l []string) []string { if l == nil { return []string{} diff --git a/web/api/v1/translate_ast_test.go b/web/api/v1/translate_ast_test.go new file mode 100644 index 0000000000..50befb1962 --- /dev/null +++ b/web/api/v1/translate_ast_test.go @@ -0,0 +1,199 @@ +// Copyright The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package v1 + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/prometheus/prometheus/promql/parser" +) + +func TestTranslateASTDurationExpressions(t *testing.T) { + p := parser.NewParser(parser.Options{}) + + type tc struct { + name string + query string + wantType string + wantFields map[string]any + } + + testcases := []tc{ + { + name: "regular matrix selector", + query: `foo[5m]`, + wantType: "matrixSelector", + wantFields: map[string]any{ + "range": int64(5 * 60 * 1000), + "rangeExpr": nil, + "offset": int64(0), + "offsetExpr": nil, + }, + }, + { + name: "regular matrix selector with offset", + query: `foo[5m] offset 1m`, + wantType: "matrixSelector", + wantFields: map[string]any{ + "range": int64(5 * 60 * 1000), + "rangeExpr": nil, + "offset": int64(60 * 1000), + "offsetExpr": nil, + }, + }, + { + name: "matrix selector range expression", + query: `foo[5m+1m]`, + wantType: "matrixSelector", + wantFields: map[string]any{ + "range": int64(0), + "rangeExpr": durationExpr("+", durationNumber("300", true), durationNumber("60", true), false), + }, + }, + { + name: "matrix selector range expression with offset expression", + query: `foo[5m+1m] offset (10m/2)`, + wantType: "matrixSelector", + wantFields: map[string]any{ + "rangeExpr": durationExpr("+", durationNumber("300", true), durationNumber("60", true), false), + "offset": int64(0), + "offsetExpr": durationExpr("/", durationNumber("600", true), durationNumber("2", false), true), + }, + }, + { + name: "complex matrix selector range expression", + query: `foo[max(step(),5m+3m) ]`, + wantType: "matrixSelector", + wantFields: map[string]any{ + "range": int64(0), + "rangeExpr": durationExpr("max", + durationExpr("step", nil, nil, false), + durationExpr("+", durationNumber("300", true), durationNumber("180", true), false), + false, + ), + }, + }, + { + name: "nested min and max matrix selector range expression", + query: `foo[min(max(step(),5m+3m),10m-2m)]`, + wantType: "matrixSelector", + wantFields: map[string]any{ + "range": int64(0), + "rangeExpr": durationExpr("min", + durationExpr("max", + durationExpr("step", nil, nil, false), + durationExpr("+", durationNumber("300", true), durationNumber("180", true), false), + false, + ), + durationExpr("-", durationNumber("600", true), durationNumber("120", true), false), + false, + ), + }, + }, + { + name: "range preprocessor expression", + query: `foo[range()]`, + wantType: "matrixSelector", + wantFields: map[string]any{ + "range": int64(0), + "rangeExpr": durationExpr("range", nil, nil, false), + }, + }, + { + name: "regular subquery selector", + query: `foo[5m:1m]`, + wantType: "subquery", + wantFields: map[string]any{ + "range": int64(5 * 60 * 1000), + "rangeExpr": nil, + "step": int64(60 * 1000), + "stepExpr": nil, + "offset": int64(0), + "offsetExpr": nil, + }, + }, + { + name: "subquery selector duration expressions", + query: `foo[4s+4s:1s*2] offset (5s-8)`, + wantType: "subquery", + wantFields: map[string]any{ + "range": int64(0), + "rangeExpr": durationExpr("+", durationNumber("4", true), durationNumber("4", true), false), + "step": int64(0), + "stepExpr": durationExpr("*", durationNumber("1", true), durationNumber("2", false), false), + "offset": int64(0), + "offsetExpr": durationExpr("-", durationNumber("5", true), durationNumber("8", false), true), + }, + }, + { + name: "regular vector selector offset", + query: `foo offset 5m`, + wantType: "vectorSelector", + wantFields: map[string]any{ + "offset": int64(5 * 60 * 1000), + "offsetExpr": nil, + }, + }, + { + name: "vector selector offset expression", + query: `foo offset -min(5s,step()+8s)`, + wantType: "vectorSelector", + wantFields: map[string]any{ + "offset": int64(0), + "offsetExpr": durationExpr("-", nil, + durationExpr("min", + durationNumber("5", true), + durationExpr("+", durationExpr("step", nil, nil, false), durationNumber("8", true), false), + false, + ), + false, + ), + }, + }, + } + + for _, tcase := range testcases { + t.Run(tcase.name, func(t *testing.T) { + expr, err := p.ParseExpr(tcase.query) + require.NoError(t, err) + + got := translateAST(expr).(map[string]any) + require.Equal(t, tcase.wantType, got["type"]) + for field, want := range tcase.wantFields { + require.Contains(t, got, field) + require.Equal(t, want, got[field], field) + } + }) + } +} + +func durationExpr(op string, lhs, rhs any, wrapped bool) map[string]any { + return map[string]any{ + "type": "durationExpr", + "op": op, + "lhs": lhs, + "rhs": rhs, + "wrapped": wrapped, + } +} + +func durationNumber(val string, duration bool) map[string]any { + return map[string]any{ + "type": "numberLiteral", + "val": val, + "duration": duration, + } +} From 483db9310d036473055788fe491bc604091ac597 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 6 May 2026 12:34:55 +0200 Subject: [PATCH 016/170] promql/parser: recognize range in duration expressions Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- promql/parser/lex.go | 2 +- promql/parser/parse_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/promql/parser/lex.go b/promql/parser/lex.go index 13b101e783..547b3f2a24 100644 --- a/promql/parser/lex.go +++ b/promql/parser/lex.go @@ -507,7 +507,7 @@ func lexStatements(l *Lexer) stateFn { l.emit(COLON) l.gotColon = true return lexStatements - case 's', 'S', 'm', 'M': + case 's', 'S', 'm', 'M', 'r', 'R': if l.scanDurationKeyword() { return lexStatements } diff --git a/promql/parser/parse_test.go b/promql/parser/parse_test.go index 482952ee64..b3ea1bb0f4 100644 --- a/promql/parser/parse_test.go +++ b/promql/parser/parse_test.go @@ -4718,6 +4718,32 @@ var testExpr = []struct { EndPos: 12, }, }, + { + input: `foo[2m/range()]`, + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{Start: 0, End: 3}, + }, + RangeExpr: &DurationExpr{ + Op: DIV, + LHS: &NumberLiteral{ + Val: 120, + Duration: true, + PosRange: posrange.PositionRange{Start: 4, End: 6}, + }, + RHS: &DurationExpr{ + Op: RANGE, + StartPos: 7, + EndPos: 14, + }, + }, + EndPos: 15, + }, + }, { input: `foo[-range()]`, expected: &MatrixSelector{ From 8739d37781b76f4f163e93ec24c6b4c51d59947b Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 6 May 2026 13:16:56 +0200 Subject: [PATCH 017/170] promql/parser: use map-based dispatch for duration keyword lexing Replace the hardcoded switch over start characters and keyword names with a map-driven approach. durationKeywordTokens maps lowercase keyword strings to their token types, and isDurationKeywordStartChar derives the valid start characters from that map, so adding a new duration keyword only requires one change instead of three. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- promql/parser/lex.go | 54 ++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/promql/parser/lex.go b/promql/parser/lex.go index 547b3f2a24..99620cacac 100644 --- a/promql/parser/lex.go +++ b/promql/parser/lex.go @@ -499,15 +499,15 @@ func lexStatements(l *Lexer) stateFn { l.backup() return lexKeywordOrIdentifier } - switch r { - case ':': + switch { + case r == ':': if l.gotColon { return l.errorf("unexpected colon %q", r) } l.emit(COLON) l.gotColon = true return lexStatements - case 's', 'S', 'm', 'M', 'r', 'R': + case isDurationKeywordStartChar(r): if l.scanDurationKeyword() { return lexStatements } @@ -935,6 +935,32 @@ func lexNumber(l *Lexer) stateFn { return lexStatements } +// durationKeywordTokens maps lowercase duration keyword names to their token types. +var durationKeywordTokens = map[string]ItemType{ + "step": STEP, + "range": RANGE, + "min": MIN, + "max": MAX, +} + +// durationKeywordStartChars is the set of lowercase runes that can start a duration keyword, +// derived from durationKeywordTokens. +var durationKeywordStartChars = makeDurationKeywordStartChars() + +func makeDurationKeywordStartChars() map[rune]struct{} { + m := make(map[rune]struct{}, len(durationKeywordTokens)) + for kw := range durationKeywordTokens { + m[rune(kw[0])] = struct{}{} + } + return m +} + +// isDurationKeywordStartChar reports whether r can be the first character of a duration keyword. +func isDurationKeywordStartChar(r rune) bool { + _, ok := durationKeywordStartChars[unicode.ToLower(r)] + return ok +} + func (l *Lexer) scanDurationKeyword() bool { for { switch r := l.next(); { @@ -942,24 +968,12 @@ func (l *Lexer) scanDurationKeyword() bool { // absorb. default: l.backup() - word := l.input[l.start:l.pos] - kw := strings.ToLower(word) - switch kw { - case "step": - l.emit(STEP) + word := strings.ToLower(l.input[l.start:l.pos]) + if tok, ok := durationKeywordTokens[word]; ok { + l.emit(tok) return true - case "range": - l.emit(RANGE) - return true - case "min": - l.emit(MIN) - return true - case "max": - l.emit(MAX) - return true - default: - return false } + return false } } } @@ -1239,7 +1253,7 @@ func lexDurationExpr(l *Lexer) stateFn { case r == ',': l.emit(COMMA) return lexDurationExpr - case r == 's' || r == 'S' || r == 'm' || r == 'M' || r == 'r' || r == 'R': + case isDurationKeywordStartChar(r): if l.scanDurationKeyword() { return lexDurationExpr } From fc4d0af37a2256d7e1d1d16890b1495c623c49d2 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 6 May 2026 15:27:32 +0200 Subject: [PATCH 018/170] cmd/prometheus: allow retention percentage with new data path Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- cmd/prometheus/main.go | 21 ++++++++++++++++++- cmd/prometheus/main_test.go | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/cmd/prometheus/main.go b/cmd/prometheus/main.go index 409b72f5f9..fcb655fb1e 100644 --- a/cmd/prometheus/main.go +++ b/cmd/prometheus/main.go @@ -824,7 +824,7 @@ func main() { if cfg.tsdb.MaxBytes > 0 { logger.Warn("storage.tsdb.retention.size is ignored, because storage.tsdb.retention.percentage is specified") } - if prom_runtime.FsSize(localStoragePath) == 0 { + if storagePathFsSize(localStoragePath) == 0 { fmt.Fprintln(os.Stderr, fmt.Errorf("unable to detect total capacity of metric storage at %s, please disable retention percentage (%g%%)", localStoragePath, cfg.tsdb.MaxPercentage)) os.Exit(2) } @@ -1756,6 +1756,25 @@ func computeExternalURL(u, listenAddr string) (*url.URL, error) { return eu, nil } +// storagePathFsSize returns the filesystem size for path or its closest existing parent. +func storagePathFsSize(path string) uint64 { + for { + if size := prom_runtime.FsSize(path); size > 0 { + return size + } + + if _, err := os.Stat(path); !errors.Is(err, os.ErrNotExist) { + return 0 + } + + parent := filepath.Dir(path) + if parent == path { + return 0 + } + path = parent + } +} + // readyStorage implements the Storage interface while allowing to set the actual // storage at a later point in time. type readyStorage struct { diff --git a/cmd/prometheus/main_test.go b/cmd/prometheus/main_test.go index 5e57dd9352..228898054a 100644 --- a/cmd/prometheus/main_test.go +++ b/cmd/prometheus/main_test.go @@ -148,6 +148,47 @@ func TestFailedStartupExitCode(t *testing.T) { require.Equal(t, expectedExitStatus, status.ExitStatus()) } +func TestRetentionPercentageStartsWithMissingStoragePath(t *testing.T) { + if testing.Short() { + t.Skip("skipping test in short mode.") + } + t.Parallel() + + tmpDir := t.TempDir() + if storagePathFsSize(tmpDir) == 0 { + t.Skip("skipping test because filesystem size detection is unavailable.") + } + + configFile := filepath.Join(tmpDir, "prometheus.yml") + storagePath := filepath.Join(tmpDir, "missing", "data") + + require.NoError(t, os.WriteFile(configFile, []byte(` +storage: + tsdb: + retention: + percentage: 1.5 +`), 0o777)) + + port := testutil.RandomUnprivilegedPort(t) + prom := prometheusCommandWithLogging( + t, + configFile, + port, + "--storage.tsdb.path="+storagePath, + ) + require.NoError(t, prom.Start()) + + require.Eventually(t, func() bool { + r, err := http.Get(fmt.Sprintf("http://127.0.0.1:%d/metrics", port)) + if err != nil { + return false + } + defer r.Body.Close() + return r.StatusCode == http.StatusOK + }, startupTime, 100*time.Millisecond) + require.DirExists(t, storagePath) +} + type senderFunc func(alerts ...*notifier.Alert) func (s senderFunc) Send(alerts ...*notifier.Alert) { From 1cdee43726a7b8797144fe4855db6f7612aa5ec9 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Tue, 5 May 2026 14:01:50 -0400 Subject: [PATCH 019/170] tsdb: fix init race that lets initialized() return true before maxTime is set initTime previously set minTime first and maxTime second. Because Head.initialized() keys only off minTime, a concurrent Head.Appender call could observe initialized() == true while maxTime was still math.MinInt64. h.appender() then computes appendableMinValidTime as MaxTime() - chunkRange/2, which underflows to a large positive number and rejects in-range samples with ErrOutOfBounds. Set maxTime first, then minTime. The CAS-loser wait now spins on minTime instead of maxTime, preserving the existing anti-deadlock timeout. AppenderV2 shares the same gate, so this single change covers both paths. The TestHead_InitAppenderRace_ErrOutOfBounds test added in #17963 is now stable across 1000 iterations (and 100 iterations under -race). Relates to #17941 Builds on #17963 Co-Authored-By: Claude Opus 4.7 (1M context) Signed-off-by: Owen Williams --- tsdb/head_append.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tsdb/head_append.go b/tsdb/head_append.go index 558c39292c..f2b89653af 100644 --- a/tsdb/head_append.go +++ b/tsdb/head_append.go @@ -117,11 +117,17 @@ func (a *initAppender) AppendSTZeroSample(ref storage.SeriesRef, lset labels.Lab // initTime initializes a head with the first timestamp. This only needs to be called // for a completely fresh head with an empty WAL. func (h *Head) initTime(t int64) { - if !h.minTime.CompareAndSwap(math.MaxInt64, t) { - // Concurrent appends that are initializing. - // Wait until h.maxTime is swapped to avoid minTime/maxTime races. + // maxTime must be set before minTime, because initialized() keys off minTime. + // If minTime were set first, a concurrent Head.Appender call could observe + // initialized() == true while maxTime is still math.MinInt64; the resulting + // underflow in appendableMinValidTime would reject in-range samples with + // ErrOutOfBounds. + if !h.maxTime.CompareAndSwap(math.MinInt64, t) { + // Another goroutine already won the init race. Wait until it also sets + // minTime, so callers that next read initialized() can rely on both + // bounds being valid. antiDeadlockTimeout := time.After(500 * time.Millisecond) - for h.maxTime.Load() == math.MinInt64 { + for h.minTime.Load() == math.MaxInt64 { select { case <-antiDeadlockTimeout: return @@ -130,8 +136,7 @@ func (h *Head) initTime(t int64) { } return } - // Ensure that max time is initialized to at least the min time we just set. - h.maxTime.CompareAndSwap(math.MinInt64, t) + h.minTime.CompareAndSwap(math.MaxInt64, t) } func (a *initAppender) GetRef(lset labels.Labels, hash uint64) (storage.SeriesRef, labels.Labels) { From da1f89e7360a19c5de2b0df4b43411ac706a76a9 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Wed, 6 May 2026 14:33:03 -0400 Subject: [PATCH 020/170] tsdb(wal): st-per-sample for histograms initial code and benchmarks (#18221) Implements ST for Histograms and Float Histograms (and their custom bucket cousins) in WAL. New tests, new benchmarks. Part of https://github.com/prometheus/prometheus/issues/17790 ```release-notes [CHANGE] Adds Start Time value to all WAL Histogram samples in memory, and therefore may increase memory usage. ``` Signed-off-by: Owen Williams --- tsdb/agent/db.go | 4 +- tsdb/agent/db_append_v2_test.go | 26 +- tsdb/agent/db_test.go | 8 +- tsdb/db_append_v2_test.go | 4 +- tsdb/db_test.go | 8 +- tsdb/head_test.go | 4 +- tsdb/head_wal.go | 8 +- tsdb/record/bench_test.go | 361 ++++++++++++++++++---- tsdb/record/record.go | 368 +++++++++++++++++++---- tsdb/record/record_test.go | 514 ++++++++++++++++++++++++++++++++ tsdb/wlog/checkpoint.go | 30 +- tsdb/wlog/checkpoint_test.go | 138 ++++++++- tsdb/wlog/watcher.go | 4 +- util/testrecord/record.go | 122 ++++++++ 14 files changed, 1461 insertions(+), 138 deletions(-) diff --git a/tsdb/agent/db.go b/tsdb/agent/db.go index d908f429a0..f7d5cd2c67 100644 --- a/tsdb/agent/db.go +++ b/tsdb/agent/db.go @@ -518,7 +518,7 @@ func (db *DB) loadWAL(r *wlog.Reader, duplicateRefToValidRef map[chunks.HeadSeri return } decoded <- samples - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: histograms := db.walReplayHistogramsPool.Get()[:0] histograms, err = dec.HistogramSamples(rec, histograms) if err != nil { @@ -530,7 +530,7 @@ func (db *DB) loadWAL(r *wlog.Reader, duplicateRefToValidRef map[chunks.HeadSeri return } decoded <- histograms - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: floatHistograms := db.walReplayFloatHistogramsPool.Get()[:0] floatHistograms, err = dec.FloatHistogramSamples(rec, floatHistograms) if err != nil { diff --git a/tsdb/agent/db_append_v2_test.go b/tsdb/agent/db_append_v2_test.go index 92a5bb8f35..9b5863fe41 100644 --- a/tsdb/agent/db_append_v2_test.go +++ b/tsdb/agent/db_append_v2_test.go @@ -232,12 +232,36 @@ func TestCommit_AppendV2(t *testing.T) { walSamplesCount += len(samples) case record.HistogramSamples, record.CustomBucketsHistogramSamples: + if enableSTStorage { + t.Errorf("Got V1 Samples when ST enabled") + } + var histograms []record.RefHistogramSample + histograms, err = dec.HistogramSamples(rec, histograms) + require.NoError(t, err) + walHistogramCount += len(histograms) + + case record.HistogramSamplesV2: + if !enableSTStorage { + t.Errorf("Got V2 Samples when ST disabled") + } var histograms []record.RefHistogramSample histograms, err = dec.HistogramSamples(rec, histograms) require.NoError(t, err) walHistogramCount += len(histograms) case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + if enableSTStorage { + t.Errorf("Got V1 Samples when ST enabled") + } + var floatHistograms []record.RefFloatHistogramSample + floatHistograms, err = dec.FloatHistogramSamples(rec, floatHistograms) + require.NoError(t, err) + walFloatHistogramCount += len(floatHistograms) + + case record.FloatHistogramSamplesV2: + if !enableSTStorage { + t.Errorf("Got V2 Samples when ST disabled") + } var floatHistograms []record.RefFloatHistogramSample floatHistograms, err = dec.FloatHistogramSamples(rec, floatHistograms) require.NoError(t, err) @@ -375,7 +399,7 @@ func TestRollbackAppendV2(t *testing.T) { case record.Exemplars: t.Errorf("should not have found exemplars") - case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.HistogramSamplesV2, record.FloatHistogramSamplesV2: t.Errorf("should not have found histograms") default: diff --git a/tsdb/agent/db_test.go b/tsdb/agent/db_test.go index 74dc7fd1b9..51077ca1e2 100644 --- a/tsdb/agent/db_test.go +++ b/tsdb/agent/db_test.go @@ -288,13 +288,13 @@ func TestCommit(t *testing.T) { require.NoError(t, err) walSamplesCount += len(samples) - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: var histograms []record.RefHistogramSample histograms, err = dec.HistogramSamples(rec, histograms) require.NoError(t, err) walHistogramCount += len(histograms) - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: var floatHistograms []record.RefFloatHistogramSample floatHistograms, err = dec.FloatHistogramSamples(rec, floatHistograms) require.NoError(t, err) @@ -430,13 +430,13 @@ func TestRollback(t *testing.T) { require.NoError(t, err) walExemplarsCount += len(exemplars) - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: var histograms []record.RefHistogramSample histograms, err = dec.HistogramSamples(rec, histograms) require.NoError(t, err) walHistogramCount += len(histograms) - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: var floatHistograms []record.RefFloatHistogramSample floatHistograms, err = dec.FloatHistogramSamples(rec, floatHistograms) require.NoError(t, err) diff --git a/tsdb/db_append_v2_test.go b/tsdb/db_append_v2_test.go index 0bb1763f3d..a584051ea4 100644 --- a/tsdb/db_append_v2_test.go +++ b/tsdb/db_append_v2_test.go @@ -205,13 +205,13 @@ func TestDataNotAvailableAfterRollback_AppendV2(t *testing.T) { require.NoError(t, err) walExemplarsCount += len(exemplars) - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: var histograms []record.RefHistogramSample histograms, err = dec.HistogramSamples(rec, histograms) require.NoError(t, err) walHistogramCount += len(histograms) - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: var floatHistograms []record.RefFloatHistogramSample floatHistograms, err = dec.FloatHistogramSamples(rec, floatHistograms) require.NoError(t, err) diff --git a/tsdb/db_test.go b/tsdb/db_test.go index 1758518e6f..ba9c0242e5 100644 --- a/tsdb/db_test.go +++ b/tsdb/db_test.go @@ -407,13 +407,13 @@ func TestDataNotAvailableAfterRollback(t *testing.T) { require.NoError(t, err) walExemplarsCount += len(exemplars) - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: var histograms []record.RefHistogramSample histograms, err = dec.HistogramSamples(rec, histograms) require.NoError(t, err) walHistogramCount += len(histograms) - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: var floatHistograms []record.RefFloatHistogramSample floatHistograms, err = dec.FloatHistogramSamples(rec, floatHistograms) require.NoError(t, err) @@ -4567,11 +4567,11 @@ func testOOOWALWrite(t *testing.T, markers, err := dec.MmapMarkers(rec, nil) require.NoError(t, err) records = append(records, markers) - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: histogramSamples, err := dec.HistogramSamples(rec, nil) require.NoError(t, err) records = append(records, histogramSamples) - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: floatHistogramSamples, err := dec.FloatHistogramSamples(rec, nil) require.NoError(t, err) records = append(records, floatHistogramSamples) diff --git a/tsdb/head_test.go b/tsdb/head_test.go index aa2c39ffee..078d1100a6 100644 --- a/tsdb/head_test.go +++ b/tsdb/head_test.go @@ -164,11 +164,11 @@ func readTestWAL(t testing.TB, dir string) (recs []any) { samples, err := dec.Samples(rec, nil) require.NoError(t, err) recs = append(recs, samples) - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: samples, err := dec.HistogramSamples(rec, nil) require.NoError(t, err) recs = append(recs, samples) - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: samples, err := dec.FloatHistogramSamples(rec, nil) require.NoError(t, err) recs = append(recs, samples) diff --git a/tsdb/head_wal.go b/tsdb/head_wal.go index d4fff5561f..590dc05055 100644 --- a/tsdb/head_wal.go +++ b/tsdb/head_wal.go @@ -206,7 +206,7 @@ func (h *Head) loadWAL(r *wlog.Reader, syms *labels.SymbolTable, multiRef map[ch return } decoded <- exemplars - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: hists := h.wlReplayHistogramsPool.Get()[:0] hists, err = dec.HistogramSamples(r.Record(), hists) if err != nil { @@ -218,7 +218,7 @@ func (h *Head) loadWAL(r *wlog.Reader, syms *labels.SymbolTable, multiRef map[ch return } decoded <- hists - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: hists := h.wlReplayFloatHistogramsPool.Get()[:0] hists, err = dec.FloatHistogramSamples(r.Record(), hists) if err != nil { @@ -838,7 +838,7 @@ func (h *Head) loadWBL(r *wlog.Reader, syms *labels.SymbolTable, multiRef map[ch return } decodedCh <- markers - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: hists := h.wlReplayHistogramsPool.Get()[:0] hists, err = dec.HistogramSamples(rec, hists) if err != nil { @@ -850,7 +850,7 @@ func (h *Head) loadWBL(r *wlog.Reader, syms *labels.SymbolTable, multiRef map[ch return } decodedCh <- hists - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: hists := h.wlReplayFloatHistogramsPool.Get()[:0] hists, err = dec.FloatHistogramSamples(rec, hists) if err != nil { diff --git a/tsdb/record/bench_test.go b/tsdb/record/bench_test.go index 1420fffc46..8c12b5656d 100644 --- a/tsdb/record/bench_test.go +++ b/tsdb/record/bench_test.go @@ -120,88 +120,335 @@ var ( testrecord.WorstCase1000, testrecord.WorstCase1000WithSTSamples, } - UseV2 = true + versions = []struct { + name string + enableST bool + }{ + {"V1", false}, + {"V2", true}, + } ) +//nolint:godot /* - export bench=encode-v2 && go test ./tsdb/record/... \ + go test ./tsdb/record/... \ -run '^$' -bench '^BenchmarkEncode_Samples' \ -benchtime 5s -count 6 -cpu 2 -timeout 999m \ - | tee ${bench}.txt + | tee encode.txt + +benchstat -col /version encode.txt */ func BenchmarkEncode_Samples(b *testing.B) { - for _, compr := range compressions { - for _, data := range dataCases { - b.Run(fmt.Sprintf("compr=%v/data=%v", compr, data), func(b *testing.B) { - var ( - samples = testrecord.GenTestRefSamplesCase(b, data) - enc = record.Encoder{EnableSTStorage: UseV2} - buf []byte - cBuf []byte - ) + for _, ver := range versions { + for _, compr := range compressions { + for _, data := range dataCases { + b.Run(fmt.Sprintf("version=%s/compr=%v/data=%v", ver.name, compr, data), func(b *testing.B) { + var ( + samples = testrecord.GenTestRefSamplesCase(b, data) + enc = record.Encoder{EnableSTStorage: ver.enableST} + buf []byte + cBuf []byte + ) - cEnc, err := compression.NewEncoder() - require.NoError(b, err) + cEnc, err := compression.NewEncoder() + require.NoError(b, err) - // Warm up. - buf = enc.Samples(samples, buf[:0]) - cBuf, _, err = cEnc.Encode(compr, buf, cBuf[:0]) - require.NoError(b, err) - - b.ReportAllocs() - b.ResetTimer() - for b.Loop() { + // Warm up. buf = enc.Samples(samples, buf[:0]) - b.ReportMetric(float64(len(buf)), "B/rec") + cBuf, _, err = cEnc.Encode(compr, buf, cBuf[:0]) + require.NoError(b, err) - cBuf, _, _ = cEnc.Encode(compr, buf, cBuf[:0]) - b.ReportMetric(float64(len(cBuf)), "B/compressed-rec") - } - }) + b.ReportAllocs() + b.ResetTimer() + for b.Loop() { + buf = enc.Samples(samples, buf[:0]) + b.ReportMetric(float64(len(buf)), "B/rec") + + cBuf, _, _ = cEnc.Encode(compr, buf, cBuf[:0]) + b.ReportMetric(float64(len(cBuf)), "B/compressed-rec") + } + }) + } } } } +//nolint:godot /* - export bench=decode-v2 && go test ./tsdb/record/... \ + go test ./tsdb/record/... \ -run '^$' -bench '^BenchmarkDecode_Samples' \ -benchtime 5s -count 6 -cpu 2 -timeout 999m \ - | tee ${bench}.txt + | tee decode.txt + +benchstat -col /version decode.txt */ func BenchmarkDecode_Samples(b *testing.B) { - for _, compr := range compressions { - for _, data := range dataCases { - b.Run(fmt.Sprintf("compr=%v/data=%v", compr, data), func(b *testing.B) { - var ( - samples = testrecord.GenTestRefSamplesCase(b, data) - enc = record.Encoder{EnableSTStorage: UseV2} - dec record.Decoder - cDec = compression.NewDecoder() - cBuf []byte - samplesBuf []record.RefSample - ) + for _, ver := range versions { + for _, compr := range compressions { + for _, data := range dataCases { + b.Run(fmt.Sprintf("version=%s/compr=%v/data=%v", ver.name, compr, data), func(b *testing.B) { + var ( + samples = testrecord.GenTestRefSamplesCase(b, data) + enc = record.Encoder{EnableSTStorage: ver.enableST} + dec record.Decoder + cDec = compression.NewDecoder() + cBuf []byte + samplesBuf []record.RefSample + ) - buf := enc.Samples(samples, nil) + buf := enc.Samples(samples, nil) - cEnc, err := compression.NewEncoder() - require.NoError(b, err) + cEnc, err := compression.NewEncoder() + require.NoError(b, err) - buf, _, err = cEnc.Encode(compr, buf, nil) - require.NoError(b, err) + buf, _, err = cEnc.Encode(compr, buf, nil) + require.NoError(b, err) - // Warm up. - cBuf, err = cDec.Decode(compr, buf, cBuf[:0]) - require.NoError(b, err) - samplesBuf, err = dec.Samples(cBuf, samplesBuf[:0]) - require.NoError(b, err) + // Warm up. + cBuf, err = cDec.Decode(compr, buf, cBuf[:0]) + require.NoError(b, err) + samplesBuf, err = dec.Samples(cBuf, samplesBuf[:0]) + require.NoError(b, err) - b.ReportAllocs() - b.ResetTimer() - for b.Loop() { - cBuf, _ = cDec.Decode(compr, buf, cBuf[:0]) - samplesBuf, _ = dec.Samples(cBuf, samplesBuf[:0]) - } - }) + b.ReportAllocs() + b.ResetTimer() + for b.Loop() { + cBuf, _ = cDec.Decode(compr, buf, cBuf[:0]) + samplesBuf, _ = dec.Samples(cBuf, samplesBuf[:0]) + } + }) + } + } + } +} + +var ( + histDataCases = testrecord.HistDataCases + histCounts = testrecord.HistCounts +) + +//nolint:godot +/* + go test ./tsdb/record/... \ + -run '^$' -bench '^BenchmarkEncode_Histograms' \ + -benchtime 5s -count 6 -cpu 2 -timeout 999m \ + | tee encode-hist.txt + +benchstat -col /version encode-hist.txt +*/ +func BenchmarkEncode_Histograms(b *testing.B) { + for _, ver := range versions { + for _, compr := range compressions { + for _, hcase := range histDataCases { + for _, stCase := range testrecord.HistSTCases { + for _, count := range histCounts { + b.Run(fmt.Sprintf("version=%s/compr=%v/type=%s/st=%s/n=%d", ver.name, compr, hcase.Name, stCase, count), func(b *testing.B) { + var ( + samples = hcase.Gen(count, stCase) + enc = record.Encoder{EnableSTStorage: ver.enableST} + buf []byte + cBuf []byte + ) + + cEnc, err := compression.NewEncoder() + require.NoError(b, err) + + // Warm up. + if hcase.Name == "nhcb" { + buf = enc.CustomBucketsHistogramSamples(samples, buf[:0]) + } else { + buf, _ = enc.HistogramSamples(samples, buf[:0]) + } + cBuf, _, err = cEnc.Encode(compr, buf, cBuf[:0]) + require.NoError(b, err) + + b.ReportAllocs() + b.ResetTimer() + for b.Loop() { + if hcase.Name == "nhcb" { + buf = enc.CustomBucketsHistogramSamples(samples, buf[:0]) + } else { + buf, _ = enc.HistogramSamples(samples, buf[:0]) + } + b.ReportMetric(float64(len(buf)), "B/rec") + + cBuf, _, _ = cEnc.Encode(compr, buf, cBuf[:0]) + b.ReportMetric(float64(len(cBuf)), "B/compressed-rec") + } + }) + } + } + } + } + } +} + +//nolint:godot +/* + go test ./tsdb/record/... \ + -run '^$' -bench '^BenchmarkDecode_Histograms' \ + -benchtime 5s -count 6 -cpu 2 -timeout 999m \ + | tee decode-hist.txt + +benchstat -col /version decode-hist.txt +*/ +func BenchmarkDecode_Histograms(b *testing.B) { + for _, ver := range versions { + for _, compr := range compressions { + for _, hcase := range histDataCases { + for _, stCase := range testrecord.HistSTCases { + for _, count := range histCounts { + b.Run(fmt.Sprintf("version=%s/compr=%v/type=%s/st=%s/n=%d", ver.name, compr, hcase.Name, stCase, count), func(b *testing.B) { + var ( + samples = hcase.Gen(count, stCase) + enc = record.Encoder{EnableSTStorage: ver.enableST} + dec record.Decoder + cDec = compression.NewDecoder() + cBuf []byte + samplesBuf []record.RefHistogramSample + ) + + var buf []byte + if hcase.Name == "nhcb" { + buf = enc.CustomBucketsHistogramSamples(samples, nil) + } else { + buf, _ = enc.HistogramSamples(samples, nil) + } + + cEnc, err := compression.NewEncoder() + require.NoError(b, err) + buf, _, err = cEnc.Encode(compr, buf, nil) + require.NoError(b, err) + + // Warm up. + cBuf, err = cDec.Decode(compr, buf, cBuf[:0]) + require.NoError(b, err) + samplesBuf, err = dec.HistogramSamples(cBuf, samplesBuf[:0]) + require.NoError(b, err) + + b.ReportAllocs() + b.ResetTimer() + for b.Loop() { + cBuf, _ = cDec.Decode(compr, buf, cBuf[:0]) + samplesBuf, _ = dec.HistogramSamples(cBuf, samplesBuf[:0]) + } + }) + } + } + } + } + } +} + +//nolint:godot +/* + go test ./tsdb/record/... \ + -run '^$' -bench '^BenchmarkEncode_FloatHistograms' \ + -benchtime 5s -count 6 -cpu 2 -timeout 999m \ + | tee encode-fhist.txt + +benchstat -col /version encode-fhist.txt +*/ +func BenchmarkEncode_FloatHistograms(b *testing.B) { + for _, ver := range versions { + for _, compr := range compressions { + for _, hcase := range histDataCases { + for _, stCase := range testrecord.HistSTCases { + for _, count := range histCounts { + b.Run(fmt.Sprintf("version=%s/compr=%v/type=%s/st=%s/n=%d", ver.name, compr, hcase.Name, stCase, count), func(b *testing.B) { + var ( + samples = testrecord.GenFloatHistograms(hcase.Gen(count, stCase)) + enc = record.Encoder{EnableSTStorage: ver.enableST} + buf []byte + cBuf []byte + ) + + cEnc, err := compression.NewEncoder() + require.NoError(b, err) + + // Warm up. + if hcase.Name == "nhcb" { + buf = enc.CustomBucketsFloatHistogramSamples(samples, buf[:0]) + } else { + buf, _ = enc.FloatHistogramSamples(samples, buf[:0]) + } + cBuf, _, err = cEnc.Encode(compr, buf, cBuf[:0]) + require.NoError(b, err) + + b.ReportAllocs() + b.ResetTimer() + for b.Loop() { + if hcase.Name == "nhcb" { + buf = enc.CustomBucketsFloatHistogramSamples(samples, buf[:0]) + } else { + buf, _ = enc.FloatHistogramSamples(samples, buf[:0]) + } + b.ReportMetric(float64(len(buf)), "B/rec") + + cBuf, _, _ = cEnc.Encode(compr, buf, cBuf[:0]) + b.ReportMetric(float64(len(cBuf)), "B/compressed-rec") + } + }) + } + } + } + } + } +} + +//nolint:godot +/* + go test ./tsdb/record/... \ + -run '^$' -bench '^BenchmarkDecode_FloatHistograms' \ + -benchtime 5s -count 6 -cpu 2 -timeout 999m \ + | tee decode-fhist.txt + +benchstat -col /version decode-fhist.txt +*/ +func BenchmarkDecode_FloatHistograms(b *testing.B) { + for _, ver := range versions { + for _, compr := range compressions { + for _, hcase := range histDataCases { + for _, stCase := range testrecord.HistSTCases { + for _, count := range histCounts { + b.Run(fmt.Sprintf("version=%s/compr=%v/type=%s/st=%s/n=%d", ver.name, compr, hcase.Name, stCase, count), func(b *testing.B) { + var ( + samples = testrecord.GenFloatHistograms(hcase.Gen(count, stCase)) + enc = record.Encoder{EnableSTStorage: ver.enableST} + dec record.Decoder + cDec = compression.NewDecoder() + cBuf []byte + samplesBuf []record.RefFloatHistogramSample + ) + + var buf []byte + if hcase.Name == "nhcb" { + buf = enc.CustomBucketsFloatHistogramSamples(samples, nil) + } else { + buf, _ = enc.FloatHistogramSamples(samples, nil) + } + + cEnc, err := compression.NewEncoder() + require.NoError(b, err) + buf, _, err = cEnc.Encode(compr, buf, nil) + require.NoError(b, err) + + // Warm up. + cBuf, err = cDec.Decode(compr, buf, cBuf[:0]) + require.NoError(b, err) + samplesBuf, err = dec.FloatHistogramSamples(cBuf, samplesBuf[:0]) + require.NoError(b, err) + + b.ReportAllocs() + b.ResetTimer() + for b.Loop() { + cBuf, _ = cDec.Decode(compr, buf, cBuf[:0]) + samplesBuf, _ = dec.FloatHistogramSamples(cBuf, samplesBuf[:0]) + } + }) + } + } + } } } } diff --git a/tsdb/record/record.go b/tsdb/record/record.go index 2a4f45e490..b3e7e8370e 100644 --- a/tsdb/record/record.go +++ b/tsdb/record/record.go @@ -60,6 +60,10 @@ const ( CustomBucketsFloatHistogramSamples Type = 10 // SamplesV2 is an enhanced sample record with an encoding scheme that allows storing float samples with timestamp and an optional ST per sample. SamplesV2 Type = 11 + // HistogramSamplesV2 is an enhanced histogram record that supports start time per sample. + HistogramSamplesV2 Type = 12 + // FloatHistogramSamplesV2 is an enhanced float histogram record that supports start time per sample. + FloatHistogramSamplesV2 Type = 13 ) func (rt Type) String() string { @@ -69,7 +73,7 @@ func (rt Type) String() string { case Samples: return "samples" case SamplesV2: - return "samples-v2" + return "samples_v2" case Tombstones: return "tombstones" case Exemplars: @@ -82,6 +86,10 @@ func (rt Type) String() string { return "custom_buckets_histogram_samples" case CustomBucketsFloatHistogramSamples: return "custom_buckets_float_histogram_samples" + case HistogramSamplesV2: + return "histogram_samples_v2" + case FloatHistogramSamplesV2: + return "float_histogram_samples_v2" case MmapMarkers: return "mmapmarkers" case Metadata: @@ -186,19 +194,17 @@ type RefExemplar struct { } // RefHistogramSample is a histogram. -// TODO(owilliams): Add support for ST. type RefHistogramSample struct { - Ref chunks.HeadSeriesRef - T int64 - H *histogram.Histogram + Ref chunks.HeadSeriesRef + ST, T int64 + H *histogram.Histogram } // RefFloatHistogramSample is a float histogram. -// TODO(owilliams): Add support for ST. type RefFloatHistogramSample struct { - Ref chunks.HeadSeriesRef - T int64 - FH *histogram.FloatHistogram + Ref chunks.HeadSeriesRef + ST, T int64 + FH *histogram.FloatHistogram } // RefMmapMarker marks that the all the samples of the given series until now have been m-mapped to disk. @@ -226,7 +232,9 @@ func (*Decoder) Type(rec []byte) Type { return Unknown } switch t := Type(rec[0]); t { - case Series, Samples, SamplesV2, Tombstones, Exemplars, MmapMarkers, Metadata, HistogramSamples, FloatHistogramSamples, CustomBucketsHistogramSamples, CustomBucketsFloatHistogramSamples: + case Series, Samples, SamplesV2, Tombstones, Exemplars, MmapMarkers, Metadata, + HistogramSamples, FloatHistogramSamples, CustomBucketsHistogramSamples, CustomBucketsFloatHistogramSamples, + HistogramSamplesV2, FloatHistogramSamplesV2: return t } return Unknown @@ -376,33 +384,26 @@ func (*Decoder) samplesV2(dec *encoding.Decbuf, samples []RefSample) ([]RefSampl var firstT, firstST int64 for len(dec.B) > 0 && dec.Err() == nil { var prev RefSample - var ref, t, ST int64 + var ref, t, st int64 var val uint64 if len(samples) == 0 { ref = dec.Varint64() firstT = dec.Varint64() t = firstT - ST = dec.Varint64() - firstST = ST + st = dec.Varint64() + firstST = st } else { prev = samples[len(samples)-1] ref = int64(prev.Ref) + dec.Varint64() t = firstT + dec.Varint64() - stMarker := dec.Byte() - switch stMarker { - case noST: - case sameST: - ST = prev.ST - default: - ST = firstST + dec.Varint64() - } + st = readSTMarker(dec, prev.ST, firstST) } val = dec.Be64() samples = append(samples, RefSample{ Ref: chunks.HeadSeriesRef(ref), - ST: ST, + ST: st, T: t, V: math.Float64frombits(val), }) @@ -417,6 +418,18 @@ func (*Decoder) samplesV2(dec *encoding.Decbuf, samples []RefSample) ([]RefSampl return samples, nil } +func readSTMarker(buf *encoding.Decbuf, prevST, firstST int64) int64 { + stMarker := buf.Byte() + switch stMarker { + case noST: + return 0 + case sameST: + return prevST + default: + return firstST + buf.Varint64() + } +} + // Tombstones appends tombstones in rec to the given slice. func (*Decoder) Tombstones(rec []byte, tstones []tombstones.Stone) ([]tombstones.Stone, error) { dec := encoding.Decbuf{B: rec} @@ -441,6 +454,7 @@ func (*Decoder) Tombstones(rec []byte, tstones []tombstones.Stone) ([]tombstones return tstones, nil } +// Exemplars appends exemplars in rec to the given slice. func (d *Decoder) Exemplars(rec []byte, exemplars []RefExemplar) ([]RefExemplar, error) { dec := encoding.Decbuf{B: rec} t := Type(dec.Byte()) @@ -451,6 +465,7 @@ func (d *Decoder) Exemplars(rec []byte, exemplars []RefExemplar) ([]RefExemplar, return d.ExemplarsFromBuffer(&dec, exemplars) } +// ExemplarsFromBuffer appends exemplars in dec to the given slice. func (d *Decoder) ExemplarsFromBuffer(dec *encoding.Decbuf, exemplars []RefExemplar) ([]RefExemplar, error) { if dec.Len() == 0 { return exemplars, nil @@ -482,6 +497,7 @@ func (d *Decoder) ExemplarsFromBuffer(dec *encoding.Decbuf, exemplars []RefExemp return exemplars, nil } +// MmapMarkers appends mmap markers in rec to the given slice. func (*Decoder) MmapMarkers(rec []byte, markers []RefMmapMarker) ([]RefMmapMarker, error) { dec := encoding.Decbuf{B: rec} t := Type(dec.Byte()) @@ -510,12 +526,21 @@ func (*Decoder) MmapMarkers(rec []byte, markers []RefMmapMarker) ([]RefMmapMarke return markers, nil } +// HistogramSamples appends histogram samples in rec to the given slice. func (d *Decoder) HistogramSamples(rec []byte, histograms []RefHistogramSample) ([]RefHistogramSample, error) { dec := encoding.Decbuf{B: rec} - t := Type(dec.Byte()) - if t != HistogramSamples && t != CustomBucketsHistogramSamples { - return nil, errors.New("invalid record type") + switch typ := Type(dec.Byte()); typ { + case HistogramSamples, CustomBucketsHistogramSamples: + return d.histogramSamplesV1(&dec, histograms) + case HistogramSamplesV2: + return d.histogramSamplesV2(&dec, histograms) + default: + return nil, fmt.Errorf("invalid record type %v", typ) } +} + +// histogramSamplesV1 decodes V1 int-histogram records (BE64 baseRef/baseTime, varint deltas). +func (d *Decoder) histogramSamplesV1(dec *encoding.Decbuf, histograms []RefHistogramSample) ([]RefHistogramSample, error) { if dec.Len() == 0 { return histograms, nil } @@ -533,7 +558,7 @@ func (d *Decoder) HistogramSamples(rec []byte, histograms []RefHistogramSample) H: &histogram.Histogram{}, } - DecodeHistogram(&dec, rh.H) + DecodeHistogram(dec, rh.H) if !histogram.IsKnownSchema(rh.H.Schema) { d.logger.Warn("skipping histogram with unknown schema in WAL record", "schema", rh.H.Schema, "timestamp", rh.T) @@ -560,7 +585,66 @@ func (d *Decoder) HistogramSamples(rec []byte, histograms []RefHistogramSample) return histograms, nil } -// DecodeHistogram decodes a Histogram from a byte slice. +// histogramSamplesV2 decodes V2 int-histogram records. +func (d *Decoder) histogramSamplesV2(dec *encoding.Decbuf, histograms []RefHistogramSample) ([]RefHistogramSample, error) { + if dec.Len() == 0 { + return histograms, nil + } + firstRef := chunks.HeadSeriesRef(dec.Varint64()) + firstT := dec.Varint64() + firstST := dec.Varint64() + var prev *RefHistogramSample + + for len(dec.B) > 0 && dec.Err() == nil { + var ref, t, st int64 + if prev == nil { + prev = &RefHistogramSample{ + Ref: firstRef, + ST: firstST, + } + ref = int64(firstRef) + t = firstT + st = firstST + } else { + ref = int64(prev.Ref) + dec.Varint64() + t = firstT + dec.Varint64() + st = readSTMarker(dec, prev.ST, firstST) + } + + rh := RefHistogramSample{ + Ref: chunks.HeadSeriesRef(ref), + ST: st, + T: t, + H: &histogram.Histogram{}, + } + prev = &rh + DecodeHistogram(dec, rh.H) + + if !histogram.IsKnownSchema(rh.H.Schema) { + d.logger.Warn("skipping histogram with unknown schema in WAL record", "schema", rh.H.Schema, "timestamp", rh.T) + continue + } + if rh.H.Schema > histogram.ExponentialSchemaMax && rh.H.Schema <= histogram.ExponentialSchemaMaxReserved { + // This is a very slow path, but it should only happen if the + // record is from a newer Prometheus version that supports higher + // resolution. + if err := rh.H.ReduceResolution(histogram.ExponentialSchemaMax); err != nil { + return nil, fmt.Errorf("error reducing resolution of histogram #%d: %w", len(histograms)+1, err) + } + } + histograms = append(histograms, rh) + } + + if dec.Err() != nil { + return nil, fmt.Errorf("decode error after %d histograms: %w", len(histograms), dec.Err()) + } + if len(dec.B) > 0 { + return nil, fmt.Errorf("unexpected %d bytes left in entry", len(dec.B)) + } + return histograms, nil +} + +// DecodeHistogram decodes a Histogram from buf. func DecodeHistogram(buf *encoding.Decbuf, h *histogram.Histogram) { h.CounterResetHint = histogram.CounterResetHint(buf.Byte()) @@ -616,12 +700,22 @@ func DecodeHistogram(buf *encoding.Decbuf, h *histogram.Histogram) { } } +// FloatHistogramSamples appends float histogram samples in rec to the given +// slice. func (d *Decoder) FloatHistogramSamples(rec []byte, histograms []RefFloatHistogramSample) ([]RefFloatHistogramSample, error) { dec := encoding.Decbuf{B: rec} - t := Type(dec.Byte()) - if t != FloatHistogramSamples && t != CustomBucketsFloatHistogramSamples { - return nil, errors.New("invalid record type") + switch typ := Type(dec.Byte()); typ { + case FloatHistogramSamples, CustomBucketsFloatHistogramSamples: + return d.floatHistogramSamplesV1(&dec, histograms) + case FloatHistogramSamplesV2: + return d.floatHistogramSamplesV2(&dec, histograms) + default: + return nil, fmt.Errorf("invalid record type %v", typ) } +} + +// floatHistogramSamplesV1 decodes V1 float-histogram records (BE64 baseRef/baseTime, varint deltas). +func (d *Decoder) floatHistogramSamplesV1(dec *encoding.Decbuf, histograms []RefFloatHistogramSample) ([]RefFloatHistogramSample, error) { if dec.Len() == 0 { return histograms, nil } @@ -639,7 +733,7 @@ func (d *Decoder) FloatHistogramSamples(rec []byte, histograms []RefFloatHistogr FH: &histogram.FloatHistogram{}, } - DecodeFloatHistogram(&dec, rh.FH) + DecodeFloatHistogram(dec, rh.FH) if !histogram.IsKnownSchema(rh.FH.Schema) { d.logger.Warn("skipping histogram with unknown schema in WAL record", "schema", rh.FH.Schema, "timestamp", rh.T) @@ -666,7 +760,67 @@ func (d *Decoder) FloatHistogramSamples(rec []byte, histograms []RefFloatHistogr return histograms, nil } -// DecodeFloatHistogram decodes a Histogram from a byte slice. +// floatHistogramSamplesV2 decodes V2 float-histogram records. +func (d *Decoder) floatHistogramSamplesV2(dec *encoding.Decbuf, histograms []RefFloatHistogramSample) ([]RefFloatHistogramSample, error) { + if dec.Len() == 0 { + return histograms, nil + } + firstRef := chunks.HeadSeriesRef(dec.Varint64()) + firstT := dec.Varint64() + firstST := dec.Varint64() + var prev *RefFloatHistogramSample + + for len(dec.B) > 0 && dec.Err() == nil { + var ref, t, st int64 + if prev == nil { + prev = &RefFloatHistogramSample{ + Ref: firstRef, + ST: firstST, + } + ref = int64(firstRef) + t = firstT + st = firstST + } else { + ref = int64(prev.Ref) + dec.Varint64() + t = firstT + dec.Varint64() + st = readSTMarker(dec, prev.ST, firstST) + } + + rfh := RefFloatHistogramSample{ + Ref: chunks.HeadSeriesRef(ref), + ST: st, + T: t, + FH: &histogram.FloatHistogram{}, + } + prev = &rfh + DecodeFloatHistogram(dec, rfh.FH) + + if !histogram.IsKnownSchema(rfh.FH.Schema) { + d.logger.Warn("skipping histogram with unknown schema in WAL record", "schema", rfh.FH.Schema, "timestamp", rfh.T) + continue + } + if rfh.FH.Schema > histogram.ExponentialSchemaMax && rfh.FH.Schema <= histogram.ExponentialSchemaMaxReserved { + // This is a very slow path, but it should only happen if the + // record is from a newer Prometheus version that supports higher + // resolution. + if err := rfh.FH.ReduceResolution(histogram.ExponentialSchemaMax); err != nil { + return nil, fmt.Errorf("error reducing resolution of histogram #%d: %w", len(histograms)+1, err) + } + } + + histograms = append(histograms, rfh) + } + + if dec.Err() != nil { + return nil, fmt.Errorf("decode error after %d histograms: %w", len(histograms), dec.Err()) + } + if len(dec.B) > 0 { + return nil, fmt.Errorf("unexpected %d bytes left in entry", len(dec.B)) + } + return histograms, nil +} + +// DecodeFloatHistogram decodes a FloatHistogram from buf. func DecodeFloatHistogram(buf *encoding.Decbuf, fh *histogram.FloatHistogram) { fh.CounterResetHint = histogram.CounterResetHint(buf.Byte()) @@ -774,7 +928,8 @@ func EncodeLabels(buf *encoding.Encbuf, lbls labels.Labels) { } // Samples appends the encoded samples to b and returns the resulting slice. -// Depending on the ST existence it either writes Samples or SamplesWithST record. +// Depending on EnableSTStorage, it writes either a Samples or SamplesV2 +// record. func (e *Encoder) Samples(samples []RefSample, b []byte) []byte { if e.EnableSTStorage { return e.samplesV2(samples, b) @@ -782,7 +937,7 @@ func (e *Encoder) Samples(samples []RefSample, b []byte) []byte { return e.samplesV1(samples, b) } -// Samples appends the encoded samples to b and returns the resulting slice. +// samplesV1 appends the encoded samples to b and returns the resulting slice. func (*Encoder) samplesV1(samples []RefSample, b []byte) []byte { buf := encoding.Encbuf{B: b} buf.PutByte(byte(Samples)) @@ -842,20 +997,24 @@ func (*Encoder) samplesV2(samples []RefSample, b []byte) []byte { buf.PutVarint64(int64(s.Ref) - int64(prev.Ref)) buf.PutVarint64(s.T - first.T) - switch s.ST { - case 0: - buf.PutByte(noST) - case prev.ST: - buf.PutByte(sameST) - default: - buf.PutByte(explicitST) - buf.PutVarint64(s.ST - first.ST) - } + writeSTMarker(&buf, s.ST, first.ST, prev.ST) buf.PutBE64(math.Float64bits(s.V)) } return buf.Get() } +func writeSTMarker(buf *encoding.Encbuf, st, firstST, prevST int64) { + switch st { + case 0: + buf.PutByte(noST) + case prevST: + buf.PutByte(sameST) + default: + buf.PutByte(explicitST) + buf.PutVarint64(st - firstST) + } +} + // Tombstones appends the encoded tombstones to b and returns the resulting slice. func (*Encoder) Tombstones(tstones []tombstones.Stone, b []byte) []byte { buf := encoding.Encbuf{B: b} @@ -871,6 +1030,8 @@ func (*Encoder) Tombstones(tstones []tombstones.Stone, b []byte) []byte { return buf.Get() } +// Exemplars appends the encoded exemplars to b and returns the resulting +// slice. func (e *Encoder) Exemplars(exemplars []RefExemplar, b []byte) []byte { buf := encoding.Encbuf{B: b} buf.PutByte(byte(Exemplars)) @@ -884,6 +1045,7 @@ func (e *Encoder) Exemplars(exemplars []RefExemplar, b []byte) []byte { return buf.Get() } +// EncodeExemplarsIntoBuffer appends the encoded exemplars to buf. func (*Encoder) EncodeExemplarsIntoBuffer(exemplars []RefExemplar, buf *encoding.Encbuf) { // Store base timestamp and base reference number of first sample. // All samples encode their timestamp and ref as delta to those. @@ -900,6 +1062,8 @@ func (*Encoder) EncodeExemplarsIntoBuffer(exemplars []RefExemplar, buf *encoding } } +// MmapMarkers appends the encoded mmap markers to b and returns the resulting +// slice. func (*Encoder) MmapMarkers(markers []RefMmapMarker, b []byte) []byte { buf := encoding.Encbuf{B: b} buf.PutByte(byte(MmapMarkers)) @@ -912,9 +1076,17 @@ func (*Encoder) MmapMarkers(markers []RefMmapMarker, b []byte) []byte { return buf.Get() } -// HistogramSamples encode exponential histograms while returning all the excluded custom bucket histograms. -// Callers can encode the returned custom bucket histograms via CustomBucketsHistogramSamples. -func (*Encoder) HistogramSamples(histograms []RefHistogramSample, b []byte) ([]byte, []RefHistogramSample) { +// HistogramSamples encodes exponential histogram samples and returns the custom +// bucket histogram samples that must be encoded separately via +// CustomBucketsHistogramSamples. +func (e *Encoder) HistogramSamples(histograms []RefHistogramSample, b []byte) ([]byte, []RefHistogramSample) { + if e.EnableSTStorage { + return e.histogramSamplesV2(histograms, b), nil + } + return e.histogramSamplesV1(histograms, b) +} + +func (*Encoder) histogramSamplesV1(histograms []RefHistogramSample, b []byte) ([]byte, []RefHistogramSample) { buf := encoding.Encbuf{B: b} buf.PutByte(byte(HistogramSamples)) @@ -948,8 +1120,48 @@ func (*Encoder) HistogramSamples(histograms []RefHistogramSample, b []byte) ([]b return buf.Get(), customBucketHistograms } -// CustomBucketsHistogramSamples encodes given histograms as custom bucket histograms. -func (*Encoder) CustomBucketsHistogramSamples(histograms []RefHistogramSample, b []byte) []byte { +// histogramSamplesV2 encodes the given histogram samples. +func (*Encoder) histogramSamplesV2(histograms []RefHistogramSample, b []byte) []byte { + buf := encoding.Encbuf{B: b} + buf.PutByte(byte(HistogramSamplesV2)) + + if len(histograms) == 0 { + return buf.Get() + } + + var first, prev *RefHistogramSample + for _, h := range histograms { + if first == nil { + first = &h + buf.PutVarint64(int64(first.Ref)) + buf.PutVarint64(first.T) + buf.PutVarint64(first.ST) + prev = first + EncodeHistogram(&buf, h.H) + continue + } + + buf.PutVarint64(int64(h.Ref) - int64(prev.Ref)) + buf.PutVarint64(h.T - first.T) + + writeSTMarker(&buf, h.ST, first.ST, prev.ST) + EncodeHistogram(&buf, h.H) + prev = &h + } + + return buf.Get() +} + +// CustomBucketsHistogramSamples appends the encoded custom-bucket histogram +// samples to b and returns the resulting slice. +func (e *Encoder) CustomBucketsHistogramSamples(histograms []RefHistogramSample, b []byte) []byte { + if e.EnableSTStorage { + return e.histogramSamplesV2(histograms, b) + } + return e.customBucketsHistogramSamplesV1(histograms, b) +} + +func (*Encoder) customBucketsHistogramSamplesV1(histograms []RefHistogramSample, b []byte) []byte { buf := encoding.Encbuf{B: b} buf.PutByte(byte(CustomBucketsHistogramSamples)) @@ -973,7 +1185,8 @@ func (*Encoder) CustomBucketsHistogramSamples(histograms []RefHistogramSample, b return buf.Get() } -// EncodeHistogram encodes a Histogram into a byte slice. +// EncodeHistogram encodes a Histogram into a byte slice. Handles both +// regular and custom bucket histograms. func EncodeHistogram(buf *encoding.Encbuf, h *histogram.Histogram) { buf.PutByte(byte(h.CounterResetHint)) @@ -1014,9 +1227,15 @@ func EncodeHistogram(buf *encoding.Encbuf, h *histogram.Histogram) { } } -// FloatHistogramSamples encode exponential float histograms while returning all the excluded custom bucket float histograms. -// Callers can encode the returned custom bucket float histograms via CustomBucketsFloatHistogramSamples. -func (*Encoder) FloatHistogramSamples(histograms []RefFloatHistogramSample, b []byte) ([]byte, []RefFloatHistogramSample) { +// FloatHistogramSamples encodes exponential float histogram samples. +func (e *Encoder) FloatHistogramSamples(histograms []RefFloatHistogramSample, b []byte) ([]byte, []RefFloatHistogramSample) { + if e.EnableSTStorage { + return e.floatHistogramSamplesV2(histograms, b), nil + } + return e.floatHistogramSamplesV1(histograms, b) +} + +func (*Encoder) floatHistogramSamplesV1(histograms []RefFloatHistogramSample, b []byte) ([]byte, []RefFloatHistogramSample) { buf := encoding.Encbuf{B: b} buf.PutByte(byte(FloatHistogramSamples)) @@ -1051,8 +1270,49 @@ func (*Encoder) FloatHistogramSamples(histograms []RefFloatHistogramSample, b [] return buf.Get(), customBucketsFloatHistograms } -// CustomBucketsFloatHistogramSamples encodes given float histograms as custom bucket float histograms. -func (*Encoder) CustomBucketsFloatHistogramSamples(histograms []RefFloatHistogramSample, b []byte) []byte { +// floatHistogramSamplesV2 encodes exponential float histogram samples and +// splits off custom-bucket float histogram samples to be encoded later. +func (*Encoder) floatHistogramSamplesV2(histograms []RefFloatHistogramSample, b []byte) []byte { + buf := encoding.Encbuf{B: b} + buf.PutByte(byte(FloatHistogramSamplesV2)) + + if len(histograms) == 0 { + return buf.Get() + } + + var first, prev *RefFloatHistogramSample + for _, fh := range histograms { + if first == nil { + first = &fh + buf.PutVarint64(int64(first.Ref)) + buf.PutVarint64(first.T) + buf.PutVarint64(first.ST) + prev = first + EncodeFloatHistogram(&buf, fh.FH) + continue + } + + buf.PutVarint64(int64(fh.Ref) - int64(prev.Ref)) + buf.PutVarint64(fh.T - first.T) + + writeSTMarker(&buf, fh.ST, first.ST, prev.ST) + EncodeFloatHistogram(&buf, fh.FH) + prev = &fh + } + + return buf.Get() +} + +// CustomBucketsFloatHistogramSamples appends the encoded custom-bucket float +// histogram samples to b and returns the resulting slice. +func (e *Encoder) CustomBucketsFloatHistogramSamples(histograms []RefFloatHistogramSample, b []byte) []byte { + if e.EnableSTStorage { + return e.floatHistogramSamplesV2(histograms, b) + } + return e.customBucketsFloatHistogramSamplesV1(histograms, b) +} + +func (*Encoder) customBucketsFloatHistogramSamplesV1(histograms []RefFloatHistogramSample, b []byte) []byte { buf := encoding.Encbuf{B: b} buf.PutByte(byte(CustomBucketsFloatHistogramSamples)) diff --git a/tsdb/record/record_test.go b/tsdb/record/record_test.go index 970930fbe5..cd7f557512 100644 --- a/tsdb/record/record_test.go +++ b/tsdb/record/record_test.go @@ -245,6 +245,8 @@ func TestRecord_EncodeDecode(t *testing.T) { decFloatHistograms = append(decFloatHistograms, decCustomBucketsFloatHistograms...) require.Equal(t, floatHistograms, decFloatHistograms) + enc = Encoder{EnableSTStorage: true} + // Gauge integer histograms. for i := range histograms { histograms[i].H.CounterResetHint = histogram.GaugeType @@ -272,6 +274,385 @@ func TestRecord_EncodeDecode(t *testing.T) { require.NoError(t, err) decGaugeFloatHistograms = append(decGaugeFloatHistograms, decCustomBucketsGaugeFloatHistograms...) require.Equal(t, floatHistograms, decGaugeFloatHistograms) + + // V2 gauge int-histogram round-trip. V2 does not disentangle regular and custom bucket histograms, so the encoder never returns a slice of leftover items. + t.Run("V2 gauge int-histogram", func(t *testing.T) { + enc = Encoder{EnableSTStorage: true} + gaugeHistsV2 := []RefHistogramSample{ + {Ref: 56, T: 1234, ST: 1000, H: histograms[0].H}, + {Ref: 42, T: 5678, ST: 1000, H: histograms[1].H}, + {Ref: 67, T: 5678, ST: 1000, H: histograms[2].H}, + } + histSamplesV2, leftOver := enc.HistogramSamples(gaugeHistsV2, nil) + require.Nil(t, leftOver) + decHistsV2, err := dec.HistogramSamples(histSamplesV2, nil) + require.NoError(t, err) + require.Equal(t, gaugeHistsV2, decHistsV2) + }) + + // V2 gauge float-histogram round-trip. + t.Run("V2 gauge float-histogram", func(t *testing.T) { + gaugeHistsV2 := []RefHistogramSample{ + {Ref: 56, T: 1234, ST: 1000, H: histograms[0].H}, + {Ref: 42, T: 5678, ST: 1000, H: histograms[1].H}, + {Ref: 67, T: 5678, ST: 1000, H: histograms[2].H}, + } + gaugeFloatHistsV2 := make([]RefFloatHistogramSample, len(gaugeHistsV2)) + for i, h := range gaugeHistsV2 { + gaugeFloatHistsV2[i] = RefFloatHistogramSample{ + Ref: h.Ref, + T: h.T, + ST: h.ST, + FH: h.H.ToFloat(nil), + } + } + floatHistSamplesV2, leftOver := enc.FloatHistogramSamples(gaugeFloatHistsV2, nil) + require.Nil(t, leftOver) + decFloatHistsV2, err := dec.FloatHistogramSamples(floatHistSamplesV2, nil) + require.NoError(t, err) + require.Equal(t, gaugeFloatHistsV2, decFloatHistsV2) + }) + + for _, enableSTStorage := range []bool{false, true} { + t.Run(fmt.Sprintf("int-histogram empty slice stStorage=%v", enableSTStorage), func(t *testing.T) { + enc := Encoder{EnableSTStorage: enableSTStorage} + histBuf, customBuckets := enc.HistogramSamples(nil, nil) + require.Nil(t, customBuckets) + + decoded, err := dec.HistogramSamples(histBuf, nil) + require.NoError(t, err) + require.Empty(t, decoded) + }) + + t.Run(fmt.Sprintf("float-histogram empty slice stStorage=%v", enableSTStorage), func(t *testing.T) { + enc := Encoder{EnableSTStorage: enableSTStorage} + floatBuf, customBucketsFloat := enc.FloatHistogramSamples(nil, nil) + require.Nil(t, customBucketsFloat) + + decoded, err := dec.FloatHistogramSamples(floatBuf, nil) + require.NoError(t, err) + require.Empty(t, decoded) + }) + } + + // When all histograms are custom-bucket, V1 HistogramSamples must return an + // empty buffer (buf.Reset path) and pass every sample through as custom. + t.Run("V1 int-histogram all custom bucket", func(t *testing.T) { + encV1 := Encoder{} + allCustom := []RefHistogramSample{ + {Ref: 56, T: 1234, H: histograms[2].H}, + {Ref: 67, T: 5678, H: histograms[2].H}, + } + histBuf, customBuckets := encV1.HistogramSamples(allCustom, nil) + require.Empty(t, histBuf, "regular histogram buffer must be empty when all samples are custom bucket") + require.Equal(t, allCustom, customBuckets) + + customBuf := encV1.CustomBucketsHistogramSamples(customBuckets, nil) + decoded, err := dec.HistogramSamples(customBuf, nil) + require.NoError(t, err) + require.Equal(t, allCustom, decoded) + }) + + t.Run("V1 float-histogram all custom bucket", func(t *testing.T) { + encV1 := Encoder{} + allCustomFloat := []RefFloatHistogramSample{ + {Ref: 56, T: 1234, FH: histograms[2].H.ToFloat(nil)}, + {Ref: 67, T: 5678, FH: histograms[2].H.ToFloat(nil)}, + } + floatBuf, customBucketsFloat := encV1.FloatHistogramSamples(allCustomFloat, nil) + require.Empty(t, floatBuf, "regular float histogram buffer must be empty when all samples are custom bucket") + require.Equal(t, allCustomFloat, customBucketsFloat) + + customFloatBuf := encV1.CustomBucketsFloatHistogramSamples(customBucketsFloat, nil) + decoded, err := dec.FloatHistogramSamples(customFloatBuf, nil) + require.NoError(t, err) + require.Equal(t, allCustomFloat, decoded) + }) + + // Backward compat: V1-encoded histograms decode with ST=0. + t.Run("V1 backward compat int-histogram ST=0", func(t *testing.T) { + encV1 := Encoder{} + v1HistSamples, v1CustomBucketsHists := encV1.HistogramSamples(histograms, nil) + v1CustomBucketsHistSamples := encV1.CustomBucketsHistogramSamples(v1CustomBucketsHists, nil) + decV1Hists, err := dec.HistogramSamples(v1HistSamples, nil) + require.NoError(t, err) + decV1CustomBuckets, err := dec.HistogramSamples(v1CustomBucketsHistSamples, nil) + require.NoError(t, err) + for _, h := range append(decV1Hists, decV1CustomBuckets...) { + require.Equal(t, int64(0), h.ST, "V1 histogram records must decode with ST=0") + } + }) + + // Backward compat: V1-encoded float histograms decode with ST=0. + t.Run("V1 backward compat float-histogram ST=0", func(t *testing.T) { + encV1 := Encoder{} + v1FloatHistSamples, v1CustomBucketsFloatHists := encV1.FloatHistogramSamples(floatHistograms, nil) + v1CustomBucketsFloatHistSamples := encV1.CustomBucketsFloatHistogramSamples(v1CustomBucketsFloatHists, nil) + decV1FloatHists, err := dec.FloatHistogramSamples(v1FloatHistSamples, nil) + require.NoError(t, err) + decV1CustomBucketsFloatHists, err := dec.FloatHistogramSamples(v1CustomBucketsFloatHistSamples, nil) + require.NoError(t, err) + for _, h := range append(decV1FloatHists, decV1CustomBucketsFloatHists...) { + require.Equal(t, int64(0), h.ST, "V1 float histogram records must decode with ST=0") + } + }) +} + +// TestRecord_V1MixedRegularAndCustomBucketHistogramPermutations verifies that +// V1 encoding correctly splits mixed regular and custom-bucket histograms into +// separate records regardless of input ordering. The split is only meaningful +// for V1, which keeps the two record types distinct for backwards +// compatibility. See TestRecord_V2MixedRegularAndCustomBucketHistogram for the +// V2 behaviour. +func TestRecord_V1MixedRegularAndCustomBucketHistogramPermutations(t *testing.T) { + dec := NewDecoder(labels.NewSymbolTable(), promslog.NewNopLogger()) + + regularA := &histogram.Histogram{ + Count: 5, + ZeroCount: 2, + ZeroThreshold: 0.001, + Sum: 18.4, + Schema: 1, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 1, Length: 2}, + }, + PositiveBuckets: []int64{1, 1, -1, 0}, + } + regularB := &histogram.Histogram{ + Count: 11, + ZeroCount: 4, + ZeroThreshold: 0.001, + Sum: 35.5, + Schema: 1, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 2, Length: 2}, + }, + PositiveBuckets: []int64{1, 1, -1, 0}, + NegativeSpans: []histogram.Span{ + {Offset: 0, Length: 1}, + {Offset: 1, Length: 2}, + }, + NegativeBuckets: []int64{1, 2, -1}, + } + custom := &histogram.Histogram{ + Count: 8, + ZeroThreshold: 0.001, + Sum: 42.0, + Schema: histogram.CustomBucketsSchema, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 2, Length: 2}, + }, + PositiveBuckets: []int64{2, -1, 2, 0}, + CustomValues: []float64{0, 2, 4, 6, 8}, + } + + type tc struct { + name string + kinds []string + } + + testCases := []tc{ + { + name: "regular then custom", + kinds: []string{"regularA", "custom"}, + }, + { + name: "custom then regular", + kinds: []string{"custom", "regularA"}, + }, + { + name: "regular custom regular", + kinds: []string{"regularA", "custom", "regularB"}, + }, + { + name: "custom regular custom", + kinds: []string{"custom", "regularA", "custom"}, + }, + } + + buildIntSamples := func(kinds []string) []RefHistogramSample { + samples := make([]RefHistogramSample, 0, len(kinds)) + for i, kind := range kinds { + var h *histogram.Histogram + switch kind { + case "regularA": + h = regularA + case "regularB": + h = regularB + case "custom": + h = custom + default: + t.Fatalf("unknown histogram kind %q", kind) + } + + samples = append(samples, RefHistogramSample{ + Ref: chunks.HeadSeriesRef(100 + i*11), + T: int64(1000 + i*250), + H: h, + }) + } + return samples + } + + toExpectedIntPartitions := func(samples []RefHistogramSample) ([]RefHistogramSample, []RefHistogramSample) { + var regularSamples []RefHistogramSample + var customSamples []RefHistogramSample + for _, sample := range samples { + if sample.H.UsesCustomBuckets() { + customSamples = append(customSamples, sample) + continue + } + regularSamples = append(regularSamples, sample) + } + return regularSamples, customSamples + } + + toFloatSamples := func(samples []RefHistogramSample) []RefFloatHistogramSample { + floatSamples := make([]RefFloatHistogramSample, 0, len(samples)) + for _, sample := range samples { + floatSamples = append(floatSamples, RefFloatHistogramSample{ + Ref: sample.Ref, + T: sample.T, + FH: sample.H.ToFloat(nil), + }) + } + return floatSamples + } + + toExpectedFloatPartitions := func(samples []RefFloatHistogramSample) ([]RefFloatHistogramSample, []RefFloatHistogramSample) { + var regularSamples []RefFloatHistogramSample + var customSamples []RefFloatHistogramSample + for _, sample := range samples { + if sample.FH.UsesCustomBuckets() { + customSamples = append(customSamples, sample) + continue + } + regularSamples = append(regularSamples, sample) + } + return regularSamples, customSamples + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + enc := Encoder{} + + intSamples := buildIntSamples(tc.kinds) + wantRegularInt, wantCustomInt := toExpectedIntPartitions(intSamples) + + histBuf, customInt := enc.HistogramSamples(intSamples, nil) + customBuf := enc.CustomBucketsHistogramSamples(customInt, nil) + + gotRegularInt, err := dec.HistogramSamples(histBuf, nil) + require.NoError(t, err) + gotCustomInt, err := dec.HistogramSamples(customBuf, nil) + require.NoError(t, err) + + require.Equal(t, wantRegularInt, gotRegularInt) + require.Equal(t, wantCustomInt, gotCustomInt) + + floatSamples := toFloatSamples(intSamples) + wantRegularFloat, wantCustomFloat := toExpectedFloatPartitions(floatSamples) + + floatBuf, customFloat := enc.FloatHistogramSamples(floatSamples, nil) + customFloatBuf := enc.CustomBucketsFloatHistogramSamples(customFloat, nil) + + gotRegularFloat, err := dec.FloatHistogramSamples(floatBuf, nil) + require.NoError(t, err) + gotCustomFloat, err := dec.FloatHistogramSamples(customFloatBuf, nil) + require.NoError(t, err) + + require.Equal(t, wantRegularFloat, gotRegularFloat) + require.Equal(t, wantCustomFloat, gotCustomFloat) + }) + } +} + +// TestRecord_V2MixedRegularAndCustomBucketHistogram verifies that V2 encodes +// regular and custom-bucket histograms into a single HistogramSamplesV2 / +// FloatHistogramSamplesV2 record. V2 drops the V1 split because the on-wire +// format has no need to preserve backwards compatibility with readers that +// predate custom buckets. +func TestRecord_V2HistogramRoundTrip(t *testing.T) { + dec := NewDecoder(labels.NewSymbolTable(), promslog.NewNopLogger()) + + regularA := &histogram.Histogram{ + Count: 5, + ZeroCount: 2, + ZeroThreshold: 0.001, + Sum: 18.4, + Schema: 1, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 1, Length: 2}, + }, + PositiveBuckets: []int64{1, 1, -1, 0}, + } + regularB := &histogram.Histogram{ + Count: 11, + ZeroCount: 4, + ZeroThreshold: 0.001, + Sum: 35.5, + Schema: 1, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 2, Length: 2}, + }, + PositiveBuckets: []int64{1, 1, -1, 0}, + NegativeSpans: []histogram.Span{ + {Offset: 0, Length: 1}, + {Offset: 1, Length: 2}, + }, + NegativeBuckets: []int64{1, 2, -1}, + } + custom := &histogram.Histogram{ + Count: 8, + ZeroThreshold: 0.001, + Sum: 42.0, + Schema: histogram.CustomBucketsSchema, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 2, Length: 2}, + }, + PositiveBuckets: []int64{2, -1, 2, 0}, + CustomValues: []float64{0, 2, 4, 6, 8}, + } + + enc := Encoder{EnableSTStorage: true} + + intSamples := []RefHistogramSample{ + {Ref: 100, T: 1000, ST: 1000, H: regularA}, + {Ref: 111, T: 1250, ST: 1000, H: custom}, + {Ref: 122, T: 1500, ST: 1234, H: regularB}, + } + + histBuf, leftOver := enc.HistogramSamples(intSamples, nil) + require.Nil(t, leftOver, "V2 must not return a separate custom-bucket slice") + require.Equal(t, HistogramSamplesV2, dec.Type(histBuf), "V2 must emit a single HistogramSamplesV2 record for mixed inputs") + + gotInt, err := dec.HistogramSamples(histBuf, nil) + require.NoError(t, err) + require.Equal(t, intSamples, gotInt) + + floatSamples := make([]RefFloatHistogramSample, len(intSamples)) + for i, s := range intSamples { + floatSamples[i] = RefFloatHistogramSample{ + Ref: s.Ref, + T: s.T, + ST: s.ST, + FH: s.H.ToFloat(nil), + } + } + + floatBuf, leftOverFloat := enc.FloatHistogramSamples(floatSamples, nil) + require.Nil(t, leftOverFloat) + require.Equal(t, FloatHistogramSamplesV2, dec.Type(floatBuf), "V2 must emit a single FloatHistogramSamplesV2 record for mixed inputs") + + gotFloat, err := dec.FloatHistogramSamples(floatBuf, nil) + require.NoError(t, err) + require.Equal(t, floatSamples, gotFloat) } func TestRecord_DecodeInvalidHistogramSchema(t *testing.T) { @@ -348,6 +729,116 @@ func TestRecord_DecodeInvalidFloatHistogramSchema(t *testing.T) { } } +func TestRecord_DecodeV2UnknownFirstHistogramSchema(t *testing.T) { + enc := Encoder{EnableSTStorage: true} + + var output bytes.Buffer + logger := promslog.New(&promslog.Config{Writer: &output}) + dec := NewDecoder(labels.NewSymbolTable(), logger) + histograms := []RefHistogramSample{ + { + Ref: 56, + ST: 1000, + T: 1234, + H: &histogram.Histogram{ + Count: 5, + ZeroCount: 2, + ZeroThreshold: 0.001, + Sum: 18.4, + Schema: -100, // "unknown" schema + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 1, Length: 2}, + }, + PositiveBuckets: []int64{1, 1, -1, 0}, + }, + }, + { + Ref: 42, + ST: 1000, + T: 5678, + H: &histogram.Histogram{ + Count: 11, + ZeroCount: 4, + ZeroThreshold: 0.001, + Sum: 35.5, + Schema: 1, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 2, Length: 2}, + }, + PositiveBuckets: []int64{1, 1, -1, 0}, + NegativeSpans: []histogram.Span{ + {Offset: 0, Length: 1}, + {Offset: 1, Length: 2}, + }, + NegativeBuckets: []int64{1, 2, -1}, + }, + }, + } + histSamples, _ := enc.HistogramSamples(histograms, nil) + decHistograms, err := dec.HistogramSamples(histSamples, nil) + require.NoError(t, err) + require.Equal(t, histograms[1:], decHistograms) + // Ensure that the schema ID above is actually unknown. If this fails then + // someone started using that value. + require.Contains(t, output.String(), "skipping histogram with unknown schema in WAL record") +} + +func TestRecord_DecodeV2UnknownFirstFloatHistogramSchema(t *testing.T) { + enc := Encoder{EnableSTStorage: true} + + var output bytes.Buffer + logger := promslog.New(&promslog.Config{Writer: &output}) + dec := NewDecoder(labels.NewSymbolTable(), logger) + histograms := []RefFloatHistogramSample{ + { + Ref: 56, + ST: 1000, + T: 1234, + FH: &histogram.FloatHistogram{ + Count: 5, + ZeroCount: 2, + ZeroThreshold: 0.001, + Sum: 18.4, + Schema: -100, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 1, Length: 2}, + }, + PositiveBuckets: []float64{1, 1, -1, 0}, + }, + }, + { + Ref: 42, + ST: 1000, + T: 5678, + FH: &histogram.FloatHistogram{ + Count: 11, + ZeroCount: 4, + ZeroThreshold: 0.001, + Sum: 35.5, + Schema: 1, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 2, Length: 2}, + }, + PositiveBuckets: []float64{1, 1, -1, 0}, + NegativeSpans: []histogram.Span{ + {Offset: 0, Length: 1}, + {Offset: 1, Length: 2}, + }, + NegativeBuckets: []float64{1, 2, -1}, + }, + }, + } + histSamples, _ := enc.FloatHistogramSamples(histograms, nil) + decHistograms, err := dec.FloatHistogramSamples(histSamples, nil) + require.NoError(t, err) + require.Equal(t, histograms[1:], decHistograms) + require.Contains(t, output.String(), "skipping histogram with unknown schema in WAL record") +} + func TestRecord_DecodeTooHighResolutionHistogramSchema(t *testing.T) { for _, enableSTStorage := range []bool{false, true} { for _, schema := range []int32{9, 52} { @@ -597,6 +1088,8 @@ func TestRecord_Type(t *testing.T) { }, }, } + // V1 histogram type recognition (requires EnableSTStorage off). + enc = Encoder{} hists, customBucketsHistograms := enc.HistogramSamples(histograms, nil) recordType = dec.Type(hists) require.Equal(t, HistogramSamples, recordType) @@ -604,6 +1097,27 @@ func TestRecord_Type(t *testing.T) { recordType = dec.Type(customBucketsHists) require.Equal(t, CustomBucketsHistogramSamples, recordType) + // V2 histogram type recognition. + enc = Encoder{EnableSTStorage: true} + hists, leftOver := enc.HistogramSamples(histograms, nil) + require.Nil(t, leftOver) + recordType = dec.Type(hists) + require.Equal(t, HistogramSamplesV2, recordType) + + // V2 float-histogram type recognition. + floatHistograms := make([]RefFloatHistogramSample, len(histograms)) + for i, h := range histograms { + floatHistograms[i] = RefFloatHistogramSample{ + Ref: h.Ref, + T: h.T, + FH: h.H.ToFloat(nil), + } + } + floatHists, leftOverFloat := enc.FloatHistogramSamples(floatHistograms, nil) + require.Nil(t, leftOverFloat) + recordType = dec.Type(floatHists) + require.Equal(t, FloatHistogramSamplesV2, recordType) + recordType = dec.Type(nil) require.Equal(t, Unknown, recordType) diff --git a/tsdb/wlog/checkpoint.go b/tsdb/wlog/checkpoint.go index e1212b280e..47470cb836 100644 --- a/tsdb/wlog/checkpoint.go +++ b/tsdb/wlog/checkpoint.go @@ -218,7 +218,7 @@ func Checkpoint(logger *slog.Logger, w *WL, from, to int, keep func(id chunks.He stats.TotalSamples += len(samples) stats.DroppedSamples += len(samples) - len(repl) - case record.HistogramSamples: + case record.HistogramSamples, record.HistogramSamplesV2: histogramSamples, err = dec.HistogramSamples(rec, histogramSamples) if err != nil { return nil, fmt.Errorf("decode histogram samples: %w", err) @@ -231,7 +231,18 @@ func Checkpoint(logger *slog.Logger, w *WL, from, to int, keep func(id chunks.He } } if len(repl) > 0 { - buf, _ = enc.HistogramSamples(repl, buf) + var leftover []record.RefHistogramSample + buf, leftover = enc.HistogramSamples(repl, buf) + if len(leftover) > 0 { + // Flush the exponential-histogram record before + // appending the custom-bucket record so they are + // written as two separate WAL records. + if expEnd := len(buf); expEnd > start { + recs = append(recs, buf[start:expEnd]) + start = expEnd + } + buf = enc.CustomBucketsHistogramSamples(leftover, buf) + } } stats.TotalSamples += len(histogramSamples) stats.DroppedSamples += len(histogramSamples) - len(repl) @@ -252,7 +263,7 @@ func Checkpoint(logger *slog.Logger, w *WL, from, to int, keep func(id chunks.He } stats.TotalSamples += len(histogramSamples) stats.DroppedSamples += len(histogramSamples) - len(repl) - case record.FloatHistogramSamples: + case record.FloatHistogramSamples, record.FloatHistogramSamplesV2: floatHistogramSamples, err = dec.FloatHistogramSamples(rec, floatHistogramSamples) if err != nil { return nil, fmt.Errorf("decode float histogram samples: %w", err) @@ -265,7 +276,18 @@ func Checkpoint(logger *slog.Logger, w *WL, from, to int, keep func(id chunks.He } } if len(repl) > 0 { - buf, _ = enc.FloatHistogramSamples(repl, buf) + var floatLeftover []record.RefFloatHistogramSample + buf, floatLeftover = enc.FloatHistogramSamples(repl, buf) + if len(floatLeftover) > 0 { + // Flush the exponential-float-histogram record before + // appending the custom-bucket record so they are + // written as two separate WAL records. + if expEnd := len(buf); expEnd > start { + recs = append(recs, buf[start:expEnd]) + start = expEnd + } + buf = enc.CustomBucketsFloatHistogramSamples(floatLeftover, buf) + } } stats.TotalSamples += len(floatHistogramSamples) stats.DroppedSamples += len(floatHistogramSamples) - len(repl) diff --git a/tsdb/wlog/checkpoint_test.go b/tsdb/wlog/checkpoint_test.go index 9056aab70b..baf8c2d79f 100644 --- a/tsdb/wlog/checkpoint_test.go +++ b/tsdb/wlog/checkpoint_test.go @@ -332,14 +332,14 @@ func TestCheckpoint(t *testing.T) { require.GreaterOrEqual(t, s.T, last/2, "sample with wrong timestamp") } samplesInCheckpoint += len(samples) - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: histograms, err := dec.HistogramSamples(rec, nil) require.NoError(t, err) for _, h := range histograms { require.GreaterOrEqual(t, h.T, last/2, "histogram with wrong timestamp") } histogramsInCheckpoint += len(histograms) - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: floatHistograms, err := dec.FloatHistogramSamples(rec, nil) require.NoError(t, err) for _, h := range floatHistograms { @@ -385,6 +385,140 @@ func TestCheckpoint(t *testing.T) { } } +// TestCheckpointV2HistogramsToV1 verifies that when a WAL contains V2 histogram +// records (where exponential and custom-bucket histograms are interleaved in a +// single record) and Checkpoint is asked to re-encode them using the V1 encoder, +// the custom-bucket histograms returned as leftover by the V1 encoder are not +// dropped. They must be re-encoded as a separate CustomBuckets(Float)Histogram +// record in the checkpoint. +func TestCheckpointV2HistogramsToV1(t *testing.T) { + t.Parallel() + + expH := &histogram.Histogram{ + Count: 5, ZeroCount: 2, ZeroThreshold: 0.001, Sum: 18.4, Schema: 1, + PositiveSpans: []histogram.Span{{Offset: 0, Length: 2}, {Offset: 1, Length: 2}}, + PositiveBuckets: []int64{1, 1, -1, 0}, + } + cbH := &histogram.Histogram{ + Count: 5, ZeroCount: 2, ZeroThreshold: 0.001, Sum: 18.4, Schema: histogram.CustomBucketsSchema, + PositiveSpans: []histogram.Span{{Offset: 0, Length: 2}, {Offset: 1, Length: 2}}, + PositiveBuckets: []int64{1, 1, -1, 0}, + CustomValues: []float64{0, 1, 2, 3, 4}, + } + + dir := t.TempDir() + + encV2 := record.Encoder{EnableSTStorage: true} + w, err := NewSize(nil, nil, dir, 128*1024, compression.None) + require.NoError(t, err) + + require.NoError(t, w.Log(encV2.Series([]record.RefSeries{ + {Ref: 0, Labels: labels.FromStrings("a", "b", "c", "exp0")}, + {Ref: 1, Labels: labels.FromStrings("a", "b", "c", "cb1")}, + {Ref: 2, Labels: labels.FromStrings("a", "b", "c", "exp2")}, + {Ref: 3, Labels: labels.FromStrings("a", "b", "c", "cb3")}, + }, nil))) + + // V2 encoder writes exp and custom-bucket histograms into a single + // HistogramSamplesV2 record (interleaved). Verify there is no leftover. + histSamples := []record.RefHistogramSample{ + {Ref: 0, T: 1000, H: expH}, + {Ref: 1, T: 1000, H: cbH}, + {Ref: 0, T: 2000, H: expH}, + {Ref: 1, T: 2000, H: cbH}, + } + histRec, leftover := encV2.HistogramSamples(histSamples, nil) + require.Empty(t, leftover, "v2 encoder must not return leftover") + require.NoError(t, w.Log(histRec)) + + floatHistSamples := make([]record.RefFloatHistogramSample, len(histSamples)) + for i, h := range histSamples { + floatHistSamples[i] = record.RefFloatHistogramSample{ + Ref: h.Ref + 2, // float series live at refs 2 and 3. + T: h.T, + FH: h.H.ToFloat(nil), + } + } + floatHistRec, floatLeftover := encV2.FloatHistogramSamples(floatHistSamples, nil) + require.Empty(t, floatLeftover, "v2 encoder must not return leftover") + require.NoError(t, w.Log(floatHistRec)) + + require.NoError(t, w.Close()) + + _, last, err := Segments(w.Dir()) + require.NoError(t, err) + + // Re-open so Checkpoint can take a read lock on the directory. + w, err = NewSize(nil, nil, dir, 128*1024, compression.None) + require.NoError(t, err) + t.Cleanup(func() { w.Close() }) + + // Run Checkpoint with V1 encoding (enableSTStorage=false) to force the + // V1 leftover path in checkpoint.go. + stats, err := Checkpoint(promslog.NewNopLogger(), w, 0, last, func(_ chunks.HeadSeriesRef) bool { return true }, 0, false) + require.NoError(t, err) + require.Equal(t, len(histSamples)+len(floatHistSamples), stats.TotalSamples) + require.Zero(t, stats.DroppedSamples, "no histogram samples should be dropped") + + cpDir := CheckpointDir(w.Dir(), last) + sr, err := NewSegmentsReader(cpDir) + require.NoError(t, err) + t.Cleanup(func() { sr.Close() }) + + dec := record.NewDecoder(labels.NewSymbolTable(), promslog.NewNopLogger()) + r := NewReader(sr) + + // For each V1 record type we expect to see exactly 2 samples for a + // specific series ref, with the matching UsesCustomBuckets flag. + type expectation struct { + ref chunks.HeadSeriesRef + usesCB bool + seen, samples int + } + expects := map[record.Type]*expectation{ + record.HistogramSamples: {ref: 0, usesCB: false}, + record.CustomBucketsHistogramSamples: {ref: 1, usesCB: true}, + record.FloatHistogramSamples: {ref: 2, usesCB: false}, + record.CustomBucketsFloatHistogramSamples: {ref: 3, usesCB: true}, + } + + for r.Next() { + rec := r.Record() + typ := dec.Type(rec) + exp, ok := expects[typ] + switch typ { + case record.HistogramSamples, record.CustomBucketsHistogramSamples: + hs, err := dec.HistogramSamples(rec, nil) + require.NoError(t, err) + exp.seen++ + exp.samples += len(hs) + for _, h := range hs { + require.Equal(t, exp.ref, h.Ref) + require.Equal(t, exp.usesCB, h.H.UsesCustomBuckets()) + } + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + fhs, err := dec.FloatHistogramSamples(rec, nil) + require.NoError(t, err) + exp.seen++ + exp.samples += len(fhs) + for _, h := range fhs { + require.Equal(t, exp.ref, h.Ref) + require.Equal(t, exp.usesCB, h.FH.UsesCustomBuckets()) + } + case record.HistogramSamplesV2, record.FloatHistogramSamplesV2: + t.Fatalf("unexpected V2 record in V1 checkpoint: %v", typ) + default: + require.False(t, ok, "unhandled expected type %v", typ) + } + } + require.NoError(t, r.Err()) + + for typ, exp := range expects { + require.Positive(t, exp.seen, "expected record type %v in checkpoint", typ) + require.Equal(t, 2, exp.samples, "expected 2 samples in record type %v", typ) + } +} + func TestCheckpointNoTmpFolderAfterError(t *testing.T) { for _, enableSTStorage := range []bool{false, true} { t.Run("enableSTStorage="+strconv.FormatBool(enableSTStorage), func(t *testing.T) { diff --git a/tsdb/wlog/watcher.go b/tsdb/wlog/watcher.go index aedf16fecf..196a284d50 100644 --- a/tsdb/wlog/watcher.go +++ b/tsdb/wlog/watcher.go @@ -588,7 +588,7 @@ func (w *Watcher) readSegment(r *LiveReader, segmentNum int, tail bool) error { } w.writer.AppendExemplars(exemplars) - case record.HistogramSamples, record.CustomBucketsHistogramSamples: + case record.HistogramSamples, record.CustomBucketsHistogramSamples, record.HistogramSamplesV2: // Skip if "native histograms over remote write" is not enabled. if !w.sendHistograms { break @@ -618,7 +618,7 @@ func (w *Watcher) readSegment(r *LiveReader, segmentNum int, tail bool) error { w.writer.AppendHistograms(histogramsToSend) } - case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples: + case record.FloatHistogramSamples, record.CustomBucketsFloatHistogramSamples, record.FloatHistogramSamplesV2: // Skip if "native histograms over remote write" is not enabled. if !w.sendHistograms { break diff --git a/util/testrecord/record.go b/util/testrecord/record.go index e5071d42c8..6ec61f8981 100644 --- a/util/testrecord/record.go +++ b/util/testrecord/record.go @@ -17,6 +17,7 @@ import ( "math" "testing" + "github.com/prometheus/prometheus/model/histogram" "github.com/prometheus/prometheus/tsdb/chunks" "github.com/prometheus/prometheus/tsdb/record" ) @@ -81,6 +82,127 @@ func GenTestRefSamplesCase(t testing.TB, c RefSamplesCase) []record.RefSample { return ret } +// HistSTCase selects the start-time pattern for histogram test data generators. +type HistSTCase string + +const ( + HistNoST HistSTCase = "no-st" + HistConstST HistSTCase = "const-st" + HistPrevTST HistSTCase = "prevt-st" + HistVariableST HistSTCase = "var-st" +) + +// HistSTCases is the standard set of histogram ST cases for benchmarks. +var HistSTCases = []HistSTCase{HistNoST, HistConstST, HistPrevTST, HistVariableST} + +// applyHistST sets the ST field on histogram samples according to the given case. +func applyHistST(out []record.RefHistogramSample, stCase HistSTCase) { + switch stCase { + case HistNoST: + // Nothing to do. + case HistConstST: + for i := range out { + out[i].ST = 1709000000 + } + case HistPrevTST: + for i := range out { + if i == 0 { + continue + } + out[i].ST = out[i-1].T + } + case HistVariableST: + for i := range out { + out[i].ST = highVarianceInt(i+1) / 1024 + } + } +} + +// GenExpHistograms generates n standard exponential histograms (schema=1) +// with incrementing refs, same timestamp, and realistic bucket distributions. +// The stCase parameter controls how the ST field is populated. +func GenExpHistograms(n int, stCase HistSTCase) []record.RefHistogramSample { + out := make([]record.RefHistogramSample, n) + for i := range out { + out[i] = record.RefHistogramSample{ + Ref: chunks.HeadSeriesRef(i), + T: 1709000000 + int64(i)*15, + H: &histogram.Histogram{ + Count: uint64(10 + i%100), + ZeroCount: uint64(1 + i%5), + ZeroThreshold: 0.001, + Sum: float64(100+i) * 1.5, + Schema: 1, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 4}, + {Offset: 2, Length: 3}, + }, + PositiveBuckets: []int64{1, 2, -1, 0, 3, -2, 1}, + NegativeSpans: []histogram.Span{ + {Offset: 0, Length: 2}, + {Offset: 1, Length: 2}, + }, + NegativeBuckets: []int64{1, 1, -1, 0}, + }, + } + } + applyHistST(out, stCase) + return out +} + +// GenCustomBucketHistograms generates n custom-bucket (NHCB) histograms (schema=-53) +// with incrementing refs. The stCase parameter controls how the ST field is populated. +func GenCustomBucketHistograms(n int, stCase HistSTCase) []record.RefHistogramSample { + out := make([]record.RefHistogramSample, n) + for i := range out { + out[i] = record.RefHistogramSample{ + Ref: chunks.HeadSeriesRef(i), + T: 1709000000 + int64(i)*15, + H: &histogram.Histogram{ + Count: uint64(10 + i%100), + Sum: float64(100+i) * 1.5, + Schema: histogram.CustomBucketsSchema, + PositiveSpans: []histogram.Span{ + {Offset: 0, Length: 8}, + }, + PositiveBuckets: []int64{5, -2, 3, -1, 4, 0, -3, 2}, + CustomValues: []float64{0.001, 0.01, 0.1, 1, 10, 100, 1000}, + }, + } + } + applyHistST(out, stCase) + return out +} + +// GenFloatHistograms converts int histograms to float histograms, preserving ST. +func GenFloatHistograms(src []record.RefHistogramSample) []record.RefFloatHistogramSample { + out := make([]record.RefFloatHistogramSample, len(src)) + for i, h := range src { + out[i] = record.RefFloatHistogramSample{ + Ref: h.Ref, + ST: h.ST, + T: h.T, + FH: h.H.ToFloat(nil), + } + } + return out +} + +// HistDataCase pairs a name with a histogram generator for benchmark tables. +type HistDataCase struct { + Name string + Gen func(n int, stCase HistSTCase) []record.RefHistogramSample +} + +// HistDataCases is the standard set of histogram data cases for benchmarks. +var HistDataCases = []HistDataCase{ + {"exp", GenExpHistograms}, + {"nhcb", GenCustomBucketHistograms}, +} + +// HistCounts is the standard set of histogram counts for benchmarks. +var HistCounts = []int{10, 100, 1000} + func highVarianceInt(i int) int64 { if i%2 == 0 { return math.MinInt32 From e4e65d1247bb6f92fb1fd1ded5d0ed3486136ed3 Mon Sep 17 00:00:00 2001 From: Maksim Korotkov Date: Fri, 24 Apr 2026 22:45:00 +0300 Subject: [PATCH 021/170] promql: prevent nil pointer dereference in DurationExpr.PositionRange Fixed a bug in the `PositionRange` method where a panic occurred when `e.RHS` was nil. Previously, the code checked `if e.RHS == nil` but then immediately accessed `e.RHS.PositionRange().End`, causing a runtime error. This commit updates the logic to correctly use `e.LHS.PositionRange().End` when the RHS is missing. Fixes: ee7d5158a ("Add step(), min(a,b) and max(a,b) in promql duration expressions") Found by PostgresPro with the Svace static analyzer. Signed-off-by: Maksim Korotkov --- promql/parser/ast.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/promql/parser/ast.go b/promql/parser/ast.go index 6496095287..49608a1322 100644 --- a/promql/parser/ast.go +++ b/promql/parser/ast.go @@ -487,7 +487,7 @@ func (e *BinaryExpr) PositionRange() posrange.PositionRange { } func (e *DurationExpr) PositionRange() posrange.PositionRange { - if e.Op == STEP || e.Op == RANGE { + if e.RHS == nil && e.LHS == nil { return posrange.PositionRange{ Start: e.StartPos, End: e.EndPos, @@ -496,7 +496,7 @@ func (e *DurationExpr) PositionRange() posrange.PositionRange { if e.RHS == nil { return posrange.PositionRange{ Start: e.StartPos, - End: e.RHS.PositionRange().End, + End: e.LHS.PositionRange().End, } } if e.LHS == nil { From 91c184a899b8e8237cdd08876fba54aa5f9feb6c Mon Sep 17 00:00:00 2001 From: Bartlomiej Plotka Date: Thu, 7 May 2026 10:48:02 +0100 Subject: [PATCH 022/170] Add bwplotka as the 3.12 release shepherd (#18634) Signed-off-by: Bartlomiej Plotka --- RELEASE.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RELEASE.md b/RELEASE.md index 37193610a4..0f1e614b9f 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -21,7 +21,9 @@ Please see [the v2.55 RELEASE.md](https://github.com/prometheus/prometheus/blob/ | v3.9 | 2025-12-18 | Bryan Boreham (GitHub: @bboreham) | | v3.10 | 2026-02-05 | Ganesh Vernekar (Github: @codesome) | | v3.11 | 2026-03-25 | Julien Pivotto (GitHub: @roidelapluie) | -| v3.12 | 2026-05-06 | **volunteer welcome** | +| v3.12 | 2026-05-06 | Bartek Plotka (GitHub: @bwplotka) | +| v3.13 | 2026-06-17 | **volunteer welcome** | +| v3.14 | 2026-07-29 | **volunteer welcome** | If you are interested in volunteering please create a pull request against the [prometheus/prometheus](https://github.com/prometheus/prometheus) repository and propose yourself for the release series of your choice. From 22fbde51279243e0492b420cdd10db379bc7fd21 Mon Sep 17 00:00:00 2001 From: alexmchughdev Date: Thu, 7 May 2026 17:27:24 +0100 Subject: [PATCH 023/170] promql: reject NaN/Inf and fix overflow bound in duration expressions calculateDuration converts a float64 seconds value into a time.Duration nanoseconds value via "time.Duration(duration*1000) * time.Millisecond". Two related issues let invalid input slip through: 1. The bounds check used "duration > 1<<63-1 || duration < -1<<63", comparing a value-in-seconds against the int64 nanosecond range. The safe input range is +/- math.MaxInt64 / 1e9 seconds (about 292 years), roughly 1e9 times tighter. Arithmetic on legal duration literals (e.g. constructed via MUL/POW operators in DurationExpr) could produce a finite value that passed the check but overflowed during the final time.Duration conversion, yielding an implementation-defined int64 silently flowing into selector Range, OriginalOffset, and Step. 2. NaN compares false against everything, so a NaN duration produced by math.Pow(-1, 0.5) (and similar) bypassed both the negative-value check and the magnitude check, again producing an implementation-defined int64 in the conversion. Reject NaN and +/-Inf up front, and align the magnitude bound with the parser's offset_duration_expr rule (1<<63 / 1e9), which already had the correct unit. Add regression tests covering each new failure mode and a happy-path case just below the new bound. ```release-notes [BUGFIX] PromQL: Reject NaN, infinite, and out-of-range duration expressions instead of silently producing an out-of-range time.Duration. ``` Signed-off-by: alexmchughdev --- promql/durations.go | 13 ++++++++++++- promql/durations_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/promql/durations.go b/promql/durations.go index c660dbf464..3dc44fbbc6 100644 --- a/promql/durations.go +++ b/promql/durations.go @@ -87,10 +87,21 @@ func (v *durationVisitor) calculateDuration(expr parser.Expr, allowedNegative bo if err != nil { return 0, err } + // Reject NaN and infinities up front. NaN compares false against everything, + // so without this guard a NaN duration would slip past the bounds check + // below and produce an implementation-defined int64 in the time.Duration + // conversion at the end of this function. + if math.IsNaN(duration) || math.IsInf(duration, 0) { + return 0, fmt.Errorf("%d:%d: duration is NaN or infinite", expr.PositionRange().Start, expr.PositionRange().End) + } if duration <= 0 && !allowedNegative { return 0, fmt.Errorf("%d:%d: duration must be greater than 0", expr.PositionRange().Start, expr.PositionRange().End) } - if duration > 1<<63-1 || duration < -1<<63 { + // duration is in seconds; the conversion below produces nanoseconds in an + // int64, so the safe input range is +/- math.MaxInt64 / 1e9 seconds. Match + // the bound used by the parser for duration literals (see + // offset_duration_expr in generated_parser.y). + if duration > 1<<63/1e9 || duration < -(1<<63)/1e9 { return 0, fmt.Errorf("%d:%d: duration is out of range", expr.PositionRange().Start, expr.PositionRange().End) } return time.Duration(duration*1000) * time.Millisecond, nil diff --git a/promql/durations_test.go b/promql/durations_test.go index 2ade9077c8..3b31e92dd6 100644 --- a/promql/durations_test.go +++ b/promql/durations_test.go @@ -266,6 +266,37 @@ func TestCalculateDuration(t *testing.T) { }, errorMessage: "modulo by zero", }, + { + name: "NaN from negative base raised to fractional power", + expr: &parser.DurationExpr{ + LHS: &parser.NumberLiteral{Val: -1}, + RHS: &parser.NumberLiteral{Val: 0.5}, + Op: parser.POW, + }, + errorMessage: "duration is NaN or infinite", + allowedNegative: true, + }, + { + name: "infinity from huge power", + expr: &parser.DurationExpr{ + LHS: &parser.NumberLiteral{Val: 2}, + RHS: &parser.NumberLiteral{Val: 1e10}, + Op: parser.POW, + }, + errorMessage: "duration is NaN or infinite", + }, + { + name: "duration exceeds time.Duration range", + expr: &parser.NumberLiteral{Val: 1e10}, + errorMessage: "duration is out of range", + }, + { + name: "duration just below the upper bound is accepted", + expr: &parser.NumberLiteral{Val: 1e9}, + // 1e9 seconds is below 1<<63/1e9 seconds (~9.22e9), so it is + // representable as a time.Duration. The exact value is preserved. + expected: time.Duration(1e9) * time.Second, + }, } for _, tt := range tests { From 38ccf6e7fe83f3e76d2798250448384dbb43a80f Mon Sep 17 00:00:00 2001 From: bwplotka Date: Fri, 8 May 2026 09:43:29 +0100 Subject: [PATCH 025/170] fix: check bounds on remote write receive when parsing symbolized metadata Signed-off-by: bwplotka --- .../example_write_adapter/server.go | 5 ++- prompb/io/prometheus/write/v2/codec.go | 12 +++++-- prompb/rwcommon/codec_test.go | 24 +++++++++++++- storage/remote/queue_manager_test.go | 5 ++- storage/remote/write_handler.go | 7 +++- storage/remote/write_handler_test.go | 33 ++++++++++++++++++- 6 files changed, 79 insertions(+), 7 deletions(-) diff --git a/documentation/examples/remote_storage/example_write_adapter/server.go b/documentation/examples/remote_storage/example_write_adapter/server.go index c2ec7184e3..0ced162129 100644 --- a/documentation/examples/remote_storage/example_write_adapter/server.go +++ b/documentation/examples/remote_storage/example_write_adapter/server.go @@ -104,7 +104,10 @@ func printV2(req *writev2.Request) error { if err != nil { return err } - m := ts.ToMetadata(req.Symbols) + m, err := ts.ToMetadata(req.Symbols) + if err != nil { + return err + } fmt.Println(l, m) for _, s := range ts.Samples { diff --git a/prompb/io/prometheus/write/v2/codec.go b/prompb/io/prometheus/write/v2/codec.go index ae4d0f635a..ebdd900c71 100644 --- a/prompb/io/prometheus/write/v2/codec.go +++ b/prompb/io/prometheus/write/v2/codec.go @@ -14,6 +14,8 @@ package writev2 import ( + "fmt" + "github.com/prometheus/common/model" "github.com/prometheus/prometheus/model/exemplar" @@ -30,7 +32,7 @@ func (m TimeSeries) ToLabels(b *labels.ScratchBuilder, symbols []string) (labels } // ToMetadata return model metadata from timeseries' remote metadata. -func (m TimeSeries) ToMetadata(symbols []string) metadata.Metadata { +func (m TimeSeries) ToMetadata(symbols []string) (metadata.Metadata, error) { typ := model.MetricTypeUnknown switch m.Metadata.Type { case Metadata_METRIC_TYPE_COUNTER: @@ -48,11 +50,17 @@ func (m TimeSeries) ToMetadata(symbols []string) metadata.Metadata { case Metadata_METRIC_TYPE_STATESET: typ = model.MetricTypeStateset } + if int(m.Metadata.UnitRef) >= len(symbols) { + return metadata.Metadata{}, fmt.Errorf("metadata unit_ref %d outside of symbols table (size %d)", m.Metadata.UnitRef, len(symbols)) + } + if int(m.Metadata.HelpRef) >= len(symbols) { + return metadata.Metadata{}, fmt.Errorf("metadata help_ref %d outside of symbols table (size %d)", m.Metadata.HelpRef, len(symbols)) + } return metadata.Metadata{ Type: typ, Unit: symbols[m.Metadata.UnitRef], Help: symbols[m.Metadata.HelpRef], - } + }, nil } // FromMetadataType transforms a Prometheus metricType into writev2 metricType. diff --git a/prompb/rwcommon/codec_test.go b/prompb/rwcommon/codec_test.go index ee92581f59..3b80580600 100644 --- a/prompb/rwcommon/codec_test.go +++ b/prompb/rwcommon/codec_test.go @@ -130,9 +130,31 @@ func TestToMetadata(t *testing.T) { } { t.Run("", func(t *testing.T) { ts := writev2.TimeSeries{Metadata: tc.input} - require.Equal(t, tc.expected, ts.ToMetadata(sym.Symbols())) + meta, err := ts.ToMetadata(sym.Symbols()) + require.NoError(t, err) + require.Equal(t, tc.expected, meta) }) } + + t.Run("out of bounds unit ref", func(t *testing.T) { + ts := writev2.TimeSeries{Metadata: writev2.Metadata{UnitRef: 999}} + _, err := ts.ToMetadata(sym.Symbols()) + require.Error(t, err) + require.Contains(t, err.Error(), "metadata unit_ref 999 outside of symbols table") + }) + + t.Run("out of bounds help ref", func(t *testing.T) { + ts := writev2.TimeSeries{Metadata: writev2.Metadata{HelpRef: 999}} + _, err := ts.ToMetadata(sym.Symbols()) + require.Error(t, err) + require.Contains(t, err.Error(), "metadata help_ref 999 outside of symbols table") + }) + + t.Run("empty symbols table", func(t *testing.T) { + ts := writev2.TimeSeries{Metadata: writev2.Metadata{}} + _, err := ts.ToMetadata([]string{}) + require.Error(t, err) + }) } func TestToHistogram_Empty(t *testing.T) { diff --git a/storage/remote/queue_manager_test.go b/storage/remote/queue_manager_test.go index 061f72c92c..74e5a52920 100644 --- a/storage/remote/queue_manager_test.go +++ b/storage/remote/queue_manager_test.go @@ -1216,7 +1216,10 @@ func v2RequestToWriteRequest(v2Req *writev2.Request) (*prompb.WriteRequest, erro if err != nil { return nil, fmt.Errorf("failed to convert metadata labels: %w", err) } - metadata := rts.ToMetadata(v2Req.Symbols) + metadata, err := rts.ToMetadata(v2Req.Symbols) + if err != nil { + return nil, fmt.Errorf("failed to convert metadata: %w", err) + } metricFamilyName := labels.String() diff --git a/storage/remote/write_handler.go b/storage/remote/write_handler.go index 9fdd750692..282669ea3c 100644 --- a/storage/remote/write_handler.go +++ b/storage/remote/write_handler.go @@ -319,7 +319,12 @@ func (h *writeHandler) appendV2(app storage.Appender, req *writev2.Request, rs * continue } - m := ts.ToMetadata(req.Symbols) + m, err := ts.ToMetadata(req.Symbols) + if err != nil { + badRequestErrs = append(badRequestErrs, fmt.Errorf("parsing metadata for series %v: %w", ts.LabelsRefs, err)) + samplesWithInvalidLabels += len(ts.Samples) + len(ts.Histograms) + continue + } if h.enableTypeAndUnitLabels && (m.Type != model.MetricTypeUnknown || m.Unit != "") { slb := labels.NewScratchBuilder(ls.Len() + 2) // +2 for __type__ and __unit__ ls.Range(func(l labels.Label) { diff --git a/storage/remote/write_handler_test.go b/storage/remote/write_handler_test.go index 2cf1217933..0163a311be 100644 --- a/storage/remote/write_handler_test.go +++ b/storage/remote/write_handler_test.go @@ -422,6 +422,36 @@ func TestRemoteWriteHandler_V2Message(t *testing.T) { expectedCode: http.StatusBadRequest, expectedRespBody: "parsing labels for series [1 999]: labelRefs 1 (name) = 999 (value) outside of symbols table (size 18)\n", }, + { + desc: "Partial write; first series with out-of-bounds metadata unit ref", + input: append( + []writev2.TimeSeries{{ + LabelsRefs: []uint32{1, 2}, + Metadata: writev2.Metadata{ + Type: writev2.Metadata_METRIC_TYPE_GAUGE, + UnitRef: 999, + }, + Samples: []writev2.Sample{{Value: 1, Timestamp: 1}}, + }}, + writeV2RequestFixture.Timeseries...), + expectedCode: http.StatusBadRequest, + expectedRespBody: "parsing metadata for series [1 2]: metadata unit_ref 999 outside of symbols table (size 18)\n", + }, + { + desc: "Partial write; first series with out-of-bounds metadata help ref", + input: append( + []writev2.TimeSeries{{ + LabelsRefs: []uint32{1, 2}, + Metadata: writev2.Metadata{ + Type: writev2.Metadata_METRIC_TYPE_GAUGE, + HelpRef: 999, + }, + Samples: []writev2.Sample{{Value: 1, Timestamp: 1}}, + }}, + writeV2RequestFixture.Timeseries...), + expectedCode: http.StatusBadRequest, + expectedRespBody: "parsing metadata for series [1 2]: metadata help_ref 999 outside of symbols table (size 18)\n", + }, { desc: "Partial write; TimeSeries with only exemplars (no samples or histograms)", input: append( @@ -791,7 +821,8 @@ func TestRemoteWriteHandler_V2Message(t *testing.T) { } } if tc.appendMetadata && tc.updateMetadataErr == nil { - expectedMeta := ts.ToMetadata(writeV2RequestFixture.Symbols) + expectedMeta, err := ts.ToMetadata(writeV2RequestFixture.Symbols) + require.NoError(t, err) requireEqual(t, mockMetadata{ls, expectedMeta}, appendable.metadata[m]) m++ } From ef01f33a03389d155ebabf51e9fcc7c30977cc2f Mon Sep 17 00:00:00 2001 From: Bartlomiej Plotka Date: Fri, 8 May 2026 10:17:57 +0100 Subject: [PATCH 026/170] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Bartlomiej Plotka --- prompb/io/prometheus/write/v2/codec.go | 2 +- storage/remote/write_handler.go | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/prompb/io/prometheus/write/v2/codec.go b/prompb/io/prometheus/write/v2/codec.go index ebdd900c71..034ac84da3 100644 --- a/prompb/io/prometheus/write/v2/codec.go +++ b/prompb/io/prometheus/write/v2/codec.go @@ -31,7 +31,7 @@ func (m TimeSeries) ToLabels(b *labels.ScratchBuilder, symbols []string) (labels return desymbolizeLabels(b, m.GetLabelsRefs(), symbols) } -// ToMetadata return model metadata from timeseries' remote metadata. +// ToMetadata returns model metadata from timeseries' remote metadata. func (m TimeSeries) ToMetadata(symbols []string) (metadata.Metadata, error) { typ := model.MetricTypeUnknown switch m.Metadata.Type { diff --git a/storage/remote/write_handler.go b/storage/remote/write_handler.go index 282669ea3c..e963879212 100644 --- a/storage/remote/write_handler.go +++ b/storage/remote/write_handler.go @@ -322,7 +322,6 @@ func (h *writeHandler) appendV2(app storage.Appender, req *writev2.Request, rs * m, err := ts.ToMetadata(req.Symbols) if err != nil { badRequestErrs = append(badRequestErrs, fmt.Errorf("parsing metadata for series %v: %w", ts.LabelsRefs, err)) - samplesWithInvalidLabels += len(ts.Samples) + len(ts.Histograms) continue } if h.enableTypeAndUnitLabels && (m.Type != model.MetricTypeUnknown || m.Unit != "") { From 1ae1172598022cd273f4e09f0e54adbda5a91ee7 Mon Sep 17 00:00:00 2001 From: bwplotka Date: Fri, 8 May 2026 10:18:42 +0100 Subject: [PATCH 027/170] typo Signed-off-by: bwplotka --- storage/remote/write_handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/remote/write_handler.go b/storage/remote/write_handler.go index e963879212..5e392da335 100644 --- a/storage/remote/write_handler.go +++ b/storage/remote/write_handler.go @@ -450,7 +450,7 @@ func (h *writeHandler) appendV2(app storage.Appender, req *writev2.Request, rs * continue } // TODO(bwplotka): Add strict mode which would trigger rollback of everything if needed. - // For now we keep the previously released flow (just error not debug leve) of dropping them without rollback and 5xx. + // For now we keep the previously released flow (just error not debug level) of dropping them without rollback and 5xx. h.logger.Error("failed to ingest exemplar, emitting error log, but no error for PRW caller", "err", err.Error(), "series", ls.String(), "exemplar", fmt.Sprintf("%+v", e)) } From a7fb856707140f4450e39711c158bddd2a93d54e Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Fri, 8 May 2026 12:11:03 +0200 Subject: [PATCH 028/170] ci: restrict govulncheck PR runs Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- .github/workflows/govulncheck.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/govulncheck.yml b/.github/workflows/govulncheck.yml index df4a014e56..1e13fbd990 100644 --- a/.github/workflows/govulncheck.yml +++ b/.github/workflows/govulncheck.yml @@ -2,6 +2,9 @@ name: govulncheck on: pull_request: + paths: + - VERSION + - .github/workflows/govulncheck.yml push: branches: - main From a133c21326ac3bf95586e3a7e6e4a2d3ac463c62 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Fri, 8 May 2026 13:13:34 +0200 Subject: [PATCH 029/170] promql/parser: remove debug print statements from DurationExpr.Pretty Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- promql/parser/prettier.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/promql/parser/prettier.go b/promql/parser/prettier.go index 3f769b724b..4b9ee17c1f 100644 --- a/promql/parser/prettier.go +++ b/promql/parser/prettier.go @@ -81,8 +81,6 @@ func (e *BinaryExpr) Pretty(level int) string { func (e *DurationExpr) Pretty(int) string { var s string - fmt.Println("e.LHS", e.LHS) - fmt.Println("e.RHS", e.RHS) if e.LHS == nil { // This is a unary duration expression. s = fmt.Sprintf("%s%s", e.Op, e.RHS.Pretty(0)) From 64e465dddcb080a94e996abd24fc24be90a68023 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Fri, 8 May 2026 13:59:50 +0200 Subject: [PATCH 030/170] chore: Update NPM deps for 3.12 Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- scripts/npm-deps.sh | 2 +- web/ui/mantine-ui/package.json | 40 +- web/ui/module/codemirror-promql/package.json | 14 +- web/ui/module/lezer-promql/package.json | 2 +- web/ui/package-lock.json | 560 ++++++++++--------- web/ui/package.json | 10 +- 6 files changed, 315 insertions(+), 313 deletions(-) diff --git a/scripts/npm-deps.sh b/scripts/npm-deps.sh index 73b5ecac27..c3ec50008a 100755 --- a/scripts/npm-deps.sh +++ b/scripts/npm-deps.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/web/ui/mantine-ui/package.json b/web/ui/mantine-ui/package.json index 87d24e8f4f..b9e6b774cb 100644 --- a/web/ui/mantine-ui/package.json +++ b/web/ui/mantine-ui/package.json @@ -12,26 +12,26 @@ "test": "vitest" }, "dependencies": { - "@codemirror/autocomplete": "^6.20.1", + "@codemirror/autocomplete": "^6.20.2", "@codemirror/language": "^6.12.3", - "@codemirror/lint": "^6.9.5", + "@codemirror/lint": "^6.9.6", "@codemirror/state": "^6.6.0", - "@codemirror/view": "^6.40.0", + "@codemirror/view": "^6.42.1", "@floating-ui/dom": "^1.7.6", - "@lezer/common": "^1.5.1", + "@lezer/common": "^1.5.2", "@lezer/highlight": "^1.2.3", - "@mantine/code-highlight": "^9.0.1", - "@mantine/core": "^9.0.1", - "@mantine/dates": "^9.0.1", - "@mantine/hooks": "^9.0.1", - "@mantine/notifications": "^9.0.1", + "@mantine/code-highlight": "^9.1.1", + "@mantine/core": "^9.1.1", + "@mantine/dates": "^9.1.1", + "@mantine/hooks": "^9.1.1", + "@mantine/notifications": "^9.1.1", "@microsoft/fetch-event-source": "^2.0.1", "@nexucis/fuzzy": "^0.5.1", "@nexucis/kvsearch": "^0.9.1", "@prometheus-io/codemirror-promql": "0.311.3", "@reduxjs/toolkit": "^2.11.2", - "@tabler/icons-react": "^3.40.0", - "@tanstack/react-query": "^5.95.2", + "@tabler/icons-react": "^3.43.0", + "@tanstack/react-query": "^5.100.9", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@types/lodash": "^4.17.24", @@ -40,13 +40,13 @@ "clsx": "^2.1.1", "dayjs": "^1.11.20", "highlight.js": "^11.11.1", - "lodash": "^4.17.23", - "react": "^19.2.4", - "react-dom": "^19.2.4", + "lodash": "^4.18.1", + "react": "^19.2.6", + "react-dom": "^19.2.6", "react-infinite-scroll-component": "^6.1.1", "react-redux": "^9.2.0", - "react-router-dom": "^7.13.2", - "sanitize-html": "^2.17.2", + "react-router-dom": "^7.15.0", + "sanitize-html": "^2.17.3", "uplot": "^1.6.32", "uplot-react": "^1.2.4", "use-query-params": "^2.2.2" @@ -57,18 +57,18 @@ "@eslint/js": "^9.39.4", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "@typescript-eslint/eslint-plugin": "^8.57.2", - "@typescript-eslint/parser": "^8.57.2", + "@typescript-eslint/eslint-plugin": "^8.59.2", + "@typescript-eslint/parser": "^8.59.2", "@vitejs/plugin-react": "^4.7.0", "eslint": "^9.39.4", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.5.2", "globals": "^16.5.0", "jsdom": "^25.0.1", - "postcss": "^8.5.8", + "postcss": "^8.5.14", "postcss-preset-mantine": "^1.18.0", "postcss-simple-vars": "^7.0.1", - "vite": "^6.4.1", + "vite": "^6.4.2", "vitest": "^3.2.4" } } diff --git a/web/ui/module/codemirror-promql/package.json b/web/ui/module/codemirror-promql/package.json index 32b9e7fd2d..c75a26d4d9 100644 --- a/web/ui/module/codemirror-promql/package.json +++ b/web/ui/module/codemirror-promql/package.json @@ -30,20 +30,20 @@ "homepage": "https://github.com/prometheus/prometheus/blob/main/web/ui/module/codemirror-promql/README.md", "dependencies": { "@prometheus-io/lezer-promql": "0.311.3", - "lru-cache": "^11.2.7" + "lru-cache": "^11.3.6" }, "devDependencies": { - "@codemirror/autocomplete": "^6.20.1", + "@codemirror/autocomplete": "^6.20.2", "@codemirror/language": "^6.12.3", - "@codemirror/lint": "^6.9.5", + "@codemirror/lint": "^6.9.6", "@codemirror/state": "^6.6.0", - "@codemirror/view": "^6.40.0", - "@lezer/common": "^1.5.1", + "@codemirror/view": "^6.42.1", + "@lezer/common": "^1.5.2", "@lezer/highlight": "^1.2.3", - "@lezer/lr": "^1.4.8", + "@lezer/lr": "^1.4.10", "eslint-plugin-prettier": "^5.5.5", "isomorphic-fetch": "^3.0.0", - "nock": "^14.0.11" + "nock": "^14.0.15" }, "peerDependencies": { "@codemirror/autocomplete": "^6.4.0", diff --git a/web/ui/module/lezer-promql/package.json b/web/ui/module/lezer-promql/package.json index d3f93ff577..df753ec00f 100644 --- a/web/ui/module/lezer-promql/package.json +++ b/web/ui/module/lezer-promql/package.json @@ -33,7 +33,7 @@ "devDependencies": { "@lezer/generator": "^1.8.0", "@lezer/highlight": "^1.2.3", - "@lezer/lr": "^1.4.8", + "@lezer/lr": "^1.4.10", "@rollup/plugin-node-resolve": "^16.0.3" }, "peerDependencies": { diff --git a/web/ui/package-lock.json b/web/ui/package-lock.json index 2684d424e1..9e4ebd450b 100644 --- a/web/ui/package-lock.json +++ b/web/ui/package-lock.json @@ -13,39 +13,39 @@ ], "devDependencies": { "@types/jest": "^29.5.14", - "@typescript-eslint/eslint-plugin": "^8.57.2", - "@typescript-eslint/parser": "^8.57.2", + "@typescript-eslint/eslint-plugin": "^8.59.2", + "@typescript-eslint/parser": "^8.59.2", "eslint-config-prettier": "^10.1.8", - "prettier": "^3.8.1", - "ts-jest": "^29.4.6", + "prettier": "^3.8.3", + "ts-jest": "^29.4.9", "typescript": "^5.9.3", - "vite": "^6.4.1" + "vite": "^6.4.2" } }, "mantine-ui": { "name": "@prometheus-io/mantine-ui", "version": "0.311.3", "dependencies": { - "@codemirror/autocomplete": "^6.20.1", + "@codemirror/autocomplete": "^6.20.2", "@codemirror/language": "^6.12.3", - "@codemirror/lint": "^6.9.5", + "@codemirror/lint": "^6.9.6", "@codemirror/state": "^6.6.0", - "@codemirror/view": "^6.40.0", + "@codemirror/view": "^6.42.1", "@floating-ui/dom": "^1.7.6", - "@lezer/common": "^1.5.1", + "@lezer/common": "^1.5.2", "@lezer/highlight": "^1.2.3", - "@mantine/code-highlight": "^9.0.1", - "@mantine/core": "^9.0.1", - "@mantine/dates": "^9.0.1", - "@mantine/hooks": "^9.0.1", - "@mantine/notifications": "^9.0.1", + "@mantine/code-highlight": "^9.1.1", + "@mantine/core": "^9.1.1", + "@mantine/dates": "^9.1.1", + "@mantine/hooks": "^9.1.1", + "@mantine/notifications": "^9.1.1", "@microsoft/fetch-event-source": "^2.0.1", "@nexucis/fuzzy": "^0.5.1", "@nexucis/kvsearch": "^0.9.1", "@prometheus-io/codemirror-promql": "0.311.3", "@reduxjs/toolkit": "^2.11.2", - "@tabler/icons-react": "^3.40.0", - "@tanstack/react-query": "^5.95.2", + "@tabler/icons-react": "^3.43.0", + "@tanstack/react-query": "^5.100.9", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", "@types/lodash": "^4.17.24", @@ -54,13 +54,13 @@ "clsx": "^2.1.1", "dayjs": "^1.11.20", "highlight.js": "^11.11.1", - "lodash": "^4.17.23", - "react": "^19.2.4", - "react-dom": "^19.2.4", + "lodash": "^4.18.1", + "react": "^19.2.6", + "react-dom": "^19.2.6", "react-infinite-scroll-component": "^6.1.1", "react-redux": "^9.2.0", - "react-router-dom": "^7.13.2", - "sanitize-html": "^2.17.2", + "react-router-dom": "^7.15.0", + "sanitize-html": "^2.17.3", "uplot": "^1.6.32", "uplot-react": "^1.2.4", "use-query-params": "^2.2.2" @@ -71,41 +71,139 @@ "@eslint/js": "^9.39.4", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", - "@typescript-eslint/eslint-plugin": "^8.57.2", - "@typescript-eslint/parser": "^8.57.2", + "@typescript-eslint/eslint-plugin": "^8.59.2", + "@typescript-eslint/parser": "^8.59.2", "@vitejs/plugin-react": "^4.7.0", "eslint": "^9.39.4", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.5.2", "globals": "^16.5.0", "jsdom": "^25.0.1", - "postcss": "^8.5.8", + "postcss": "^8.5.14", "postcss-preset-mantine": "^1.18.0", "postcss-simple-vars": "^7.0.1", - "vite": "^6.4.1", + "vite": "^6.4.2", "vitest": "^3.2.4" } }, + "mantine-ui/node_modules/@mantine/code-highlight": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mantine/code-highlight/-/code-highlight-9.1.1.tgz", + "integrity": "sha512-+NS5RwozXQZacKc1MzKwFf5auueyIPGpi9CTz0VWeefMeKhvtwfG1HUJbQGZa3YLdFTT7MzU6Id9M8vjzBdDPA==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1" + }, + "peerDependencies": { + "@mantine/core": "9.1.1", + "@mantine/hooks": "9.1.1", + "react": "^19.2.0", + "react-dom": "^19.2.0" + } + }, + "mantine-ui/node_modules/@mantine/core": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-9.1.1.tgz", + "integrity": "sha512-vClOZdCeZ4oLYuA/3jAOgKGQ6dXbF6ZkzpYz09Gied9nZpB7HcQeb3dcMh8UPBE4f+EM7KlYWk6dch7GoASeaA==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.27.19", + "clsx": "^2.1.1", + "react-number-format": "^5.4.5", + "react-remove-scroll": "^2.7.2", + "type-fest": "^5.6.0" + }, + "peerDependencies": { + "@mantine/hooks": "9.1.1", + "react": "^19.2.0", + "react-dom": "^19.2.0" + } + }, + "mantine-ui/node_modules/@mantine/dates": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-9.1.1.tgz", + "integrity": "sha512-P1tr/Hr+EVxppbOVpTLvaZZnM1W/r0TNpqNNMeM81xfyuKYzd7zt2/SQYb6BuudgEQfRJnAee+7bIJLEsrb0uA==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1" + }, + "peerDependencies": { + "@mantine/core": "9.1.1", + "@mantine/hooks": "9.1.1", + "dayjs": ">=1.0.0", + "react": "^19.2.0", + "react-dom": "^19.2.0" + } + }, + "mantine-ui/node_modules/@mantine/hooks": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-9.1.1.tgz", + "integrity": "sha512-tTJK73nGFyy1v214TLdvBq0be7QCoc6osfbXVuJgOH3YG85lWk9Mvvor6k+w6hC6HXSqKMqLKePyiGm83xGcMg==", + "license": "MIT", + "peerDependencies": { + "react": "^19.2.0" + } + }, + "mantine-ui/node_modules/@mantine/notifications": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-9.1.1.tgz", + "integrity": "sha512-ZfcEMMDp0BQ+yKmVp8ifPXLKej8pv9TcaRnmy2CZ07USD61E9LH5ClRAP/hxQuCyf/qLb5BPHsI7+f3K8uhj4Q==", + "license": "MIT", + "dependencies": { + "@mantine/store": "9.1.1", + "react-transition-group": "4.4.5" + }, + "peerDependencies": { + "@mantine/core": "9.1.1", + "@mantine/hooks": "9.1.1", + "react": "^19.2.0", + "react-dom": "^19.2.0" + } + }, + "mantine-ui/node_modules/@mantine/store": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@mantine/store/-/store-9.1.1.tgz", + "integrity": "sha512-kbxEU8wVGbobHlmQmk0lu9M+xCILKjuAPcMAshgzPznGLfXeE9zrB0gNT2cbk11Ik8dlV9J6Vsn9cuACyOSpfQ==", + "license": "MIT", + "peerDependencies": { + "react": "^19.2.0" + } + }, + "mantine-ui/node_modules/type-fest": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.6.0.tgz", + "integrity": "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==", + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "module/codemirror-promql": { "name": "@prometheus-io/codemirror-promql", "version": "0.311.3", "license": "Apache-2.0", "dependencies": { "@prometheus-io/lezer-promql": "0.311.3", - "lru-cache": "^11.2.7" + "lru-cache": "^11.3.6" }, "devDependencies": { - "@codemirror/autocomplete": "^6.20.1", + "@codemirror/autocomplete": "^6.20.2", "@codemirror/language": "^6.12.3", - "@codemirror/lint": "^6.9.5", + "@codemirror/lint": "^6.9.6", "@codemirror/state": "^6.6.0", - "@codemirror/view": "^6.40.0", - "@lezer/common": "^1.5.1", + "@codemirror/view": "^6.42.1", + "@lezer/common": "^1.5.2", "@lezer/highlight": "^1.2.3", - "@lezer/lr": "^1.4.8", + "@lezer/lr": "^1.4.10", "eslint-plugin-prettier": "^5.5.5", "isomorphic-fetch": "^3.0.0", - "nock": "^14.0.11" + "nock": "^14.0.15" }, "engines": { "node": ">=12.0.0" @@ -126,7 +224,7 @@ "devDependencies": { "@lezer/generator": "^1.8.0", "@lezer/highlight": "^1.2.3", - "@lezer/lr": "^1.4.8", + "@lezer/lr": "^1.4.10", "@rollup/plugin-node-resolve": "^16.0.3" }, "peerDependencies": { @@ -727,9 +825,9 @@ "peer": true }, "node_modules/@codemirror/autocomplete": { - "version": "6.20.1", - "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.1.tgz", - "integrity": "sha512-1cvg3Vz1dSSToCNlJfRA2WSI4ht3K+WplO0UMOgmUYPivCyy2oueZY6Lx7M9wThm7SDUBViRmuT+OG/i8+ON9A==", + "version": "6.20.2", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.2.tgz", + "integrity": "sha512-G5FPkgIiLjOgZMjqVjvuKQ1rGPtHogLldJr33eFJdVLtmwY+giGrlv/ewljLz6b9BSQLkjxuwBc6g6omDM+YxQ==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", @@ -765,13 +863,13 @@ } }, "node_modules/@codemirror/lint": { - "version": "6.9.5", - "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.5.tgz", - "integrity": "sha512-GElsbU9G7QT9xXhpUg1zWGmftA/7jamh+7+ydKRuT0ORpWS3wOSP0yT1FOlIZa7mIJjpVPipErsyvVqB9cfTFA==", + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.6.tgz", + "integrity": "sha512-6Kp7r6XfCi/D/5sdXieMfg9pJU1bUEx96WITuLU6ESaKizCz0QHFMjY/TaFSbigDdEAIgi93itLBIUETP4oK+A==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.35.0", + "@codemirror/view": "^6.42.0", "crelt": "^1.0.5" } }, @@ -808,9 +906,9 @@ } }, "node_modules/@codemirror/view": { - "version": "6.40.0", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.40.0.tgz", - "integrity": "sha512-WA0zdU7xfF10+5I3HhUUq3kqOx3KjqmtQ9lqZjfK7jtYk4G72YW9rezcSywpaUMCWOMlq+6E0pO1IWg1TNIhtg==", + "version": "6.42.1", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.42.1.tgz", + "integrity": "sha512-ToN3oFc0nsxNUYVF5P0ztLgbC4UPPjPtA9aKYhkOKQaZASpOUo6ISXyQLP66ctVwlDc+j6Jv0uK5IFALkiXztg==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.6.0", @@ -2051,9 +2149,9 @@ } }, "node_modules/@lezer/common": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.1.tgz", - "integrity": "sha512-6YRVG9vBkaY7p1IVxL4s44n5nUnaNnGM2/AckNgYOnxTG2kWh1vR8BMxPseWPjRNpb5VtXnMpeYAEAADoRV1Iw==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz", + "integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==", "license": "MIT" }, "node_modules/@lezer/generator": { @@ -2079,112 +2177,14 @@ } }, "node_modules/@lezer/lr": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.8.tgz", - "integrity": "sha512-bPWa0Pgx69ylNlMlPvBPryqeLYQjyJjqPx+Aupm5zydLIF3NE+6MMLT8Yi23Bd9cif9VS00aUebn+6fDIGBcDA==", + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.10.tgz", + "integrity": "sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==", "license": "MIT", "dependencies": { "@lezer/common": "^1.0.0" } }, - "node_modules/@mantine/code-highlight": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@mantine/code-highlight/-/code-highlight-9.0.1.tgz", - "integrity": "sha512-ZIZDOvQzz475GNRAbNaBQCrpXLPwAekj6vaAcnbqrFjKKACVnZPJqkELm40gM9RtBCYvMFL01fmiWZfJLUT+ag==", - "license": "MIT", - "dependencies": { - "clsx": "^2.1.1" - }, - "peerDependencies": { - "@mantine/core": "9.0.1", - "@mantine/hooks": "9.0.1", - "react": "^19.2.0", - "react-dom": "^19.2.0" - } - }, - "node_modules/@mantine/core": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@mantine/core/-/core-9.0.1.tgz", - "integrity": "sha512-kSYm8g7p8FTDysOsz9BN14TSqp10O0yAmo9HOZfwe6c08gGKQSytnSCPgnTe2h5DMfpbhTg+krROrT8WQy37fA==", - "license": "MIT", - "dependencies": { - "@floating-ui/react": "^0.27.19", - "clsx": "^2.1.1", - "react-number-format": "^5.4.5", - "react-remove-scroll": "^2.7.2", - "type-fest": "^5.5.0" - }, - "peerDependencies": { - "@mantine/hooks": "9.0.1", - "react": "^19.2.0", - "react-dom": "^19.2.0" - } - }, - "node_modules/@mantine/core/node_modules/type-fest": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.5.0.tgz", - "integrity": "sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g==", - "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@mantine/dates": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-9.0.1.tgz", - "integrity": "sha512-+zwqqQ4D2I8o/GiEStF66Mheo3abKmS0KaL3XDtDp1D7AVhKmSH3Rz27m48aqW/Kzqb2g2t3VgPzAkpuRsWdBA==", - "license": "MIT", - "dependencies": { - "clsx": "^2.1.1" - }, - "peerDependencies": { - "@mantine/core": "9.0.1", - "@mantine/hooks": "9.0.1", - "dayjs": ">=1.0.0", - "react": "^19.2.0", - "react-dom": "^19.2.0" - } - }, - "node_modules/@mantine/hooks": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-9.0.1.tgz", - "integrity": "sha512-WM/GbSD8MxZoy3X2IdrbxLq0/0ca4zMA5m7lGw9k1Vecqt1dC/nBed0IJd/w2HGs6avGs9CPlvQ8C4yBEcSnLA==", - "license": "MIT", - "peerDependencies": { - "react": "^19.2.0" - } - }, - "node_modules/@mantine/notifications": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-9.0.1.tgz", - "integrity": "sha512-og/RfURurEwTISUmgN/wcjlIE1+OxkCgcmUDZ1Jinfm1efJ8ywXl1zf/fa7/VVN4O/xZl+HMhN46OoCnW3+/bw==", - "license": "MIT", - "dependencies": { - "@mantine/store": "9.0.1", - "react-transition-group": "4.4.5" - }, - "peerDependencies": { - "@mantine/core": "9.0.1", - "@mantine/hooks": "9.0.1", - "react": "^19.2.0", - "react-dom": "^19.2.0" - } - }, - "node_modules/@mantine/store": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@mantine/store/-/store-9.0.1.tgz", - "integrity": "sha512-7jn/tX6qC71zd8Hcr/m/kQT7wCp87nvUM3p9OoJ2qX13oNCrMEXRtimYwqkOBK5Vx2hNApQY5KF183+arHU6NA==", - "license": "MIT", - "peerDependencies": { - "react": "^19.2.0" - } - }, "node_modules/@marijn/find-cluster-break": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", @@ -2758,9 +2758,9 @@ "license": "MIT" }, "node_modules/@tabler/icons": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.40.0.tgz", - "integrity": "sha512-V/Q4VgNPKubRTiLdmWjV/zscYcj5IIk+euicUtaVVqF6luSC9rDngYWgST5/yh3Mrg/mYUwRv1YVTk71Jp0twQ==", + "version": "3.43.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.43.0.tgz", + "integrity": "sha512-qXwS17Op9jqr3Asvu31fejyw8+OnRDKH7oR8nQXyUgW1pI44ET8OKG9kssy+XIvvAIyej6gZdGmviNUn1VMfPw==", "license": "MIT", "funding": { "type": "github", @@ -2768,12 +2768,12 @@ } }, "node_modules/@tabler/icons-react": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.40.0.tgz", - "integrity": "sha512-oO5+6QCnna4a//mYubx4euZfECtzQZFDGsDMIdzZUhbdyBCT+3bRVFBPueGIcemWld4Vb/0UQ39C/cmGfGylAg==", + "version": "3.43.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.43.0.tgz", + "integrity": "sha512-rXUuCQEeRbEk3lJxs3gwzdtaaITSwc/JUbp+AkqsGff5uBpzZw7eKPDk53xKoKLyjrbj82Ai4GuVG0kO89Jf5g==", "license": "MIT", "dependencies": { - "@tabler/icons": "3.40.0" + "@tabler/icons": "3.43.0" }, "funding": { "type": "github", @@ -2784,9 +2784,9 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.95.2", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.95.2.tgz", - "integrity": "sha512-o4T8vZHZET4Bib3jZ/tCW9/7080urD4c+0/AUaYVpIqOsr7y0reBc1oX3ttNaSW5mYyvZHctiQ/UOP2PfdmFEQ==", + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.9.tgz", + "integrity": "sha512-SJSFw1S8+kQ0+knv/XGfrbocWoAlT7vDKsSImtLx3ZPQmEcR46hkDjLSvynSy25N8Ms4tIEini1FuBd5k7IscQ==", "license": "MIT", "funding": { "type": "github", @@ -2794,12 +2794,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.95.2", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.95.2.tgz", - "integrity": "sha512-/wGkvLj/st5Ud1Q76KF1uFxScV7WeqN1slQx5280ycwAyYkIPGaRZAEgHxe3bjirSd5Zpwkj6zNcR4cqYni/ZA==", + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.100.9.tgz", + "integrity": "sha512-Oa44XkaI3kCNN6ME0KByU3xT3SEUNOMfZpHxL6+wFoTm+OeUFYHKdeYVe0aOXlRDm/f15sgLwEt2HDorIdW8+A==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.95.2" + "@tanstack/query-core": "5.100.9" }, "funding": { "type": "github", @@ -3127,20 +3127,20 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.2.tgz", - "integrity": "sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.2.tgz", + "integrity": "sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.57.2", - "@typescript-eslint/type-utils": "8.57.2", - "@typescript-eslint/utils": "8.57.2", - "@typescript-eslint/visitor-keys": "8.57.2", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/type-utils": "8.59.2", + "@typescript-eslint/utils": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3150,9 +3150,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.57.2", + "@typescript-eslint/parser": "^8.59.2", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -3166,16 +3166,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.2.tgz", - "integrity": "sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.2.tgz", + "integrity": "sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.57.2", - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/typescript-estree": "8.57.2", - "@typescript-eslint/visitor-keys": "8.57.2", + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", "debug": "^4.4.3" }, "engines": { @@ -3187,18 +3187,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.2.tgz", - "integrity": "sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.2.tgz", + "integrity": "sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.57.2", - "@typescript-eslint/types": "^8.57.2", + "@typescript-eslint/tsconfig-utils": "^8.59.2", + "@typescript-eslint/types": "^8.59.2", "debug": "^4.4.3" }, "engines": { @@ -3209,18 +3209,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.2.tgz", - "integrity": "sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.2.tgz", + "integrity": "sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/visitor-keys": "8.57.2" + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3231,9 +3231,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.2.tgz", - "integrity": "sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.2.tgz", + "integrity": "sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==", "dev": true, "license": "MIT", "engines": { @@ -3244,21 +3244,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.2.tgz", - "integrity": "sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.2.tgz", + "integrity": "sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/typescript-estree": "8.57.2", - "@typescript-eslint/utils": "8.57.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2", + "@typescript-eslint/utils": "8.59.2", "debug": "^4.4.3", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3269,13 +3269,13 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.2.tgz", - "integrity": "sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.2.tgz", + "integrity": "sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==", "dev": true, "license": "MIT", "engines": { @@ -3287,21 +3287,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.2.tgz", - "integrity": "sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz", + "integrity": "sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.57.2", - "@typescript-eslint/tsconfig-utils": "8.57.2", - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/visitor-keys": "8.57.2", + "@typescript-eslint/project-service": "8.59.2", + "@typescript-eslint/tsconfig-utils": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/visitor-keys": "8.59.2", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.4.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3311,7 +3311,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { @@ -3325,9 +3325,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", "dev": true, "license": "MIT", "dependencies": { @@ -3338,13 +3338,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.5" }, "engines": { "node": "18 || 20 || >=22" @@ -3354,16 +3354,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.2.tgz", - "integrity": "sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.2.tgz", + "integrity": "sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.57.2", - "@typescript-eslint/types": "8.57.2", - "@typescript-eslint/typescript-estree": "8.57.2" + "@typescript-eslint/scope-manager": "8.59.2", + "@typescript-eslint/types": "8.59.2", + "@typescript-eslint/typescript-estree": "8.59.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3374,17 +3374,17 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.57.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.2.tgz", - "integrity": "sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==", + "version": "8.59.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.2.tgz", + "integrity": "sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.57.2", + "@typescript-eslint/types": "8.59.2", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -5362,9 +5362,9 @@ "license": "ISC" }, "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6990,9 +6990,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/lodash.memoize": { @@ -7028,9 +7028,9 @@ "license": "MIT" }, "node_modules/lru-cache": { - "version": "11.2.7", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.7.tgz", - "integrity": "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==", + "version": "11.3.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.6.tgz", + "integrity": "sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==", "license": "BlueOak-1.0.0", "engines": { "node": "20 || >=22" @@ -7229,9 +7229,9 @@ "license": "MIT" }, "node_modules/nock": { - "version": "14.0.11", - "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.11.tgz", - "integrity": "sha512-u5xUnYE+UOOBA6SpELJheMCtj2Laqx15Vl70QxKo43Wz/6nMHXS7PrEioXLjXAwhmawdEMNImwKCcPhBJWbKVw==", + "version": "14.0.15", + "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.15.tgz", + "integrity": "sha512-S0a47C9pLvcYx/Ugf0H30BVBEcUgMMBDk9VJIDlJ8XGrfH2QDUD4Tgdp45qDIiHttokBG+IbsOtsvIjGR/j3bg==", "dev": true, "license": "MIT", "dependencies": { @@ -7652,9 +7652,9 @@ } }, "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", "funding": [ { "type": "opencollective", @@ -7816,9 +7816,9 @@ } }, "node_modules/prettier": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", - "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.3.tgz", + "integrity": "sha512-7igPTM53cGHMW8xWuVTydi2KO233VFiTNyF5hLJqpilHfmn8C8gPf+PS7dUT64YcXFbiMGZxS9pCSxL/Dxm/Jw==", "dev": true, "license": "MIT", "bin": { @@ -7941,24 +7941,24 @@ "peer": true }, "node_modules/react": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", - "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.6.tgz", + "integrity": "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.2.4", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", - "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "version": "19.2.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz", + "integrity": "sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==", "license": "MIT", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.4" + "react": "^19.2.6" } }, "node_modules/react-infinite-scroll-component": { @@ -8071,9 +8071,9 @@ } }, "node_modules/react-router": { - "version": "7.13.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.2.tgz", - "integrity": "sha512-tX1Aee+ArlKQP+NIUd7SE6Li+CiGKwQtbS+FfRxPX6Pe4vHOo6nr9d++u5cwg+Z8K/x8tP+7qLmujDtfrAoUJA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.15.0.tgz", + "integrity": "sha512-HW9vYwuM8f4yx66Izy8xfrzCM+SBJluoZcCbww9A1TySax11S5Vgw6fi3ZjMONw9J4gQwngL7PzkyIpJJpJ7RQ==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -8093,12 +8093,12 @@ } }, "node_modules/react-router-dom": { - "version": "7.13.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.13.2.tgz", - "integrity": "sha512-aR7SUORwTqAW0JDeiWF07e9SBE9qGpByR9I8kJT5h/FrBKxPMS6TiC7rmVO+gC0q52Bx7JnjWe8Z1sR9faN4YA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.15.0.tgz", + "integrity": "sha512-VcrVg64Fo8nwBvDscajG8gRTLIuTC6N50nb22l2HOOV4PTOHgoGp8mUjy9wLiHYoYTSYI36tUnXZgasSRFZorQ==", "license": "MIT", "dependencies": { - "react-router": "7.13.2" + "react-router": "7.15.0" }, "engines": { "node": ">=20.0.0" @@ -8320,9 +8320,9 @@ "license": "MIT" }, "node_modules/sanitize-html": { - "version": "2.17.2", - "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.2.tgz", - "integrity": "sha512-EnffJUl46VE9uvZ0XeWzObHLurClLlT12gsOk1cHyP2Ol1P0BnBnsXmShlBmWVJM+dKieQI68R0tsPY5m/B+Jg==", + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.3.tgz", + "integrity": "sha512-Kn4srCAo2+wZyvCNKCSyB2g8RQ8IkX/gQs2uqoSRNu5t9I2qvUyAVvRDiFUVAiX3N3PNuwStY0eNr+ooBHVWEg==", "license": "MIT", "dependencies": { "deepmerge": "^4.2.2", @@ -8352,10 +8352,11 @@ "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==" }, "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -8915,19 +8916,19 @@ } }, "node_modules/ts-jest": { - "version": "29.4.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", - "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", + "version": "29.4.9", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.9.tgz", + "integrity": "sha512-LTb9496gYPMCqjeDLdPrKuXtncudeV1yRZnF4Wo5l3SFi0RYEnYRNgMrFIdg+FHvfzjCyQk1cLncWVqiSX+EvQ==", "dev": true, "license": "MIT", "dependencies": { "bs-logger": "^0.2.6", "fast-json-stable-stringify": "^2.1.0", - "handlebars": "^4.7.8", + "handlebars": "^4.7.9", "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.7.3", + "semver": "^7.7.4", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, @@ -8944,7 +8945,7 @@ "babel-jest": "^29.0.0 || ^30.0.0", "jest": "^29.0.0 || ^30.0.0", "jest-util": "^29.0.0 || ^30.0.0", - "typescript": ">=4.3 <6" + "typescript": ">=4.3 <7" }, "peerDependenciesMeta": { "@babel/core": { @@ -9204,10 +9205,11 @@ } }, "node_modules/vite": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", - "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz", + "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", diff --git a/web/ui/package.json b/web/ui/package.json index 2dbe4cf049..9e24d37e2c 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -17,12 +17,12 @@ ], "devDependencies": { "@types/jest": "^29.5.14", - "@typescript-eslint/eslint-plugin": "^8.57.2", - "@typescript-eslint/parser": "^8.57.2", + "@typescript-eslint/eslint-plugin": "^8.59.2", + "@typescript-eslint/parser": "^8.59.2", "eslint-config-prettier": "^10.1.8", - "prettier": "^3.8.1", - "ts-jest": "^29.4.6", + "prettier": "^3.8.3", + "ts-jest": "^29.4.9", "typescript": "^5.9.3", - "vite": "^6.4.1" + "vite": "^6.4.2" } } From aa5927029e417d1efe7f201d60a500dafa1af90e Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Fri, 8 May 2026 15:16:25 +0200 Subject: [PATCH 031/170] discovery/stackit: use config.Secret for ServiceAccountKey and PrivateKey Fixes GHSA-39j6-789q-qxvh Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- config/config_test.go | 8 +++++--- config/testdata/conf.good.yml | 2 ++ discovery/stackit/server.go | 4 ++-- discovery/stackit/server_test.go | 7 ++++--- discovery/stackit/stackit.go | 4 ++-- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/config/config_test.go b/config/config_test.go index e5f1b98227..b364e09769 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1579,8 +1579,10 @@ var expectedConf = &Config{ HTTPClientConfig: config.DefaultHTTPClientConfig, ServiceDiscoveryConfigs: discovery.Configs{ &stackit.SDConfig{ - Project: "11111111-1111-1111-1111-111111111111", - Region: "eu01", + Project: "11111111-1111-1111-1111-111111111111", + ServiceAccountKey: "mysecret_sa_key", + PrivateKey: "mysecret_private_key", + Region: "eu01", HTTPClientConfig: config.HTTPClientConfig{ Authorization: &config.Authorization{ Type: "Bearer", @@ -2157,7 +2159,7 @@ func TestElideSecrets(t *testing.T) { yamlConfig := string(config) matches := secretRe.FindAllStringIndex(yamlConfig, -1) - require.Len(t, matches, 26, "wrong number of secret matches found") + require.Len(t, matches, 28, "wrong number of secret matches found") require.NotContains(t, yamlConfig, "mysecret", "yaml marshal reveals authentication credentials.") } diff --git a/config/testdata/conf.good.yml b/config/testdata/conf.good.yml index edc17201bf..a2f8459b24 100644 --- a/config/testdata/conf.good.yml +++ b/config/testdata/conf.good.yml @@ -422,6 +422,8 @@ scrape_configs: - job_name: stackit-servers stackit_sd_configs: - project: 11111111-1111-1111-1111-111111111111 + service_account_key: mysecret_sa_key + private_key: mysecret_private_key authorization: credentials: abcdef diff --git a/discovery/stackit/server.go b/discovery/stackit/server.go index 770ab761ed..c5d76393a5 100644 --- a/discovery/stackit/server.go +++ b/discovery/stackit/server.go @@ -90,8 +90,8 @@ func newServerDiscovery(conf *SDConfig, logger *slog.Logger) (*iaasDiscovery, er Servers: servers, NoAuth: conf.ServiceAccountKey == "" && conf.ServiceAccountKeyPath == "", - ServiceAccountKey: conf.ServiceAccountKey, - PrivateKey: conf.PrivateKey, + ServiceAccountKey: string(conf.ServiceAccountKey), + PrivateKey: string(conf.PrivateKey), ServiceAccountKeyPath: conf.ServiceAccountKeyPath, PrivateKeyPath: conf.PrivateKeyPath, CredentialsFilePath: conf.CredentialsFilePath, diff --git a/discovery/stackit/server_test.go b/discovery/stackit/server_test.go index afb9460851..3859c542de 100644 --- a/discovery/stackit/server_test.go +++ b/discovery/stackit/server_test.go @@ -21,6 +21,7 @@ import ( "encoding/pem" "testing" + "github.com/prometheus/common/config" "github.com/prometheus/common/model" "github.com/prometheus/common/promslog" "github.com/stretchr/testify/require" @@ -59,12 +60,12 @@ func TestServerSDRefresh(t *testing.T) { require.NoError(t, err) cfg := DefaultSDConfig - cfg.PrivateKey = string(pem.EncodeToMemory(&pem.Block{ + cfg.PrivateKey = config.Secret(pem.EncodeToMemory(&pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key), })) - cfg.ServiceAccountKey = `{ + cfg.ServiceAccountKey = config.Secret(`{ "Active": true, "CreatedAt": "2025-04-05T12:34:56Z", "Credentials": { @@ -79,7 +80,7 @@ func TestServerSDRefresh(t *testing.T) { "KeyType": "USER_MANAGED", "PublicKey": "...", "ValidUntil": "2025-04-05T13:34:56Z" -}` +}`) return cfg }(), diff --git a/discovery/stackit/stackit.go b/discovery/stackit/stackit.go index bae76c8897..fe5139429f 100644 --- a/discovery/stackit/stackit.go +++ b/discovery/stackit/stackit.go @@ -65,8 +65,8 @@ type SDConfig struct { Port int `yaml:"port,omitempty"` Region string `yaml:"region,omitempty"` Endpoint string `yaml:"endpoint,omitempty"` - ServiceAccountKey string `yaml:"service_account_key,omitempty"` - PrivateKey string `yaml:"private_key,omitempty"` + ServiceAccountKey config.Secret `yaml:"service_account_key,omitempty"` + PrivateKey config.Secret `yaml:"private_key,omitempty"` ServiceAccountKeyPath string `yaml:"service_account_key_path,omitempty"` PrivateKeyPath string `yaml:"private_key_path,omitempty"` CredentialsFilePath string `yaml:"credentials_file_path,omitempty"` From dd54642a477b2c4f314e4c81009894949ec7bc18 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Fri, 8 May 2026 17:41:27 +0200 Subject: [PATCH 032/170] web: reject concurrent fgprof profiles with 500, aligning with pprof Add a mutex around the fgprof handler so that only one profile can run at a time. A second concurrent request returns 500 with an error message matching the pprof behaviour for CPU profiling already in use. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- web/web.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/web/web.go b/web/web.go index 65da00ed18..51316e95c0 100644 --- a/web/web.go +++ b/web/web.go @@ -114,7 +114,10 @@ const ( Stopping ) -var fgprofHandler = fgprof.Handler() +var ( + fgprofHandler = fgprof.Handler() + fgprofMu sync.Mutex +) // withStackTracer logs the stack trace in case the request panics. The function // will re-raise the error which will then be handled by the net/http package. @@ -636,6 +639,11 @@ func serveDebug(w http.ResponseWriter, req *http.Request) { case "trace": pprof.Trace(w, req) case "fgprof": + if !fgprofMu.TryLock() { + http.Error(w, "Could not enable fgprof profiling: fgprof profiling already in use", http.StatusInternalServerError) + return + } + defer fgprofMu.Unlock() fgprofHandler.ServeHTTP(w, req) default: req.URL.Path = "/debug/pprof/" + subpath From 51d7f024dd1b1753cf46e65361d8344730598b1d Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Mon, 11 May 2026 11:34:17 +0200 Subject: [PATCH 033/170] promql: set Schema in HistogramStatsIterator to detect schema mix Without Schema being propagated in HistogramStatsIterator, histograms served through the stats-only path (e.g. histogram_count(rate(...))) all appear as Schema=0, causing the exponential/custom-bucket mismatch detection to be silently skipped. Add a test that exercises histogram_count(rate()) over a series with mixed exponential and custom bucket schemas to verify the warning is emitted. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- promql/histogram_stats_iterator.go | 4 ++++ promql/promqltest/testdata/native_histograms.test | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/promql/histogram_stats_iterator.go b/promql/histogram_stats_iterator.go index 87cc5acfbd..f6afb50b61 100644 --- a/promql/histogram_stats_iterator.go +++ b/promql/histogram_stats_iterator.go @@ -86,10 +86,14 @@ func (*HistogramStatsIterator) AtHistogram(*histogram.Histogram) (int64, *histog // performs a counter reset detection on the fly. It will return an explicit // hint (not UnknownCounterReset) if the previous sample has been accessed with // the same iterator. +// +// The returned histogram contains only Count, Sum, CounterResetHint, and Schema. +// Bucket data is intentionally omitted. func (hsi *HistogramStatsIterator) AtFloatHistogram(fh *histogram.FloatHistogram) (int64, *histogram.FloatHistogram) { populateFH := func(src *histogram.FloatHistogram, detectReset bool) { h := histogram.FloatHistogram{ CounterResetHint: src.CounterResetHint, + Schema: src.Schema, Count: src.Count, Sum: src.Sum, } diff --git a/promql/promqltest/testdata/native_histograms.test b/promql/promqltest/testdata/native_histograms.test index 88ba36c86b..ce473dc69a 100644 --- a/promql/promqltest/testdata/native_histograms.test +++ b/promql/promqltest/testdata/native_histograms.test @@ -1118,6 +1118,13 @@ eval instant at 1m30s rate(some_metric[1m30s]) expect warn msg: PromQL warning: vector contains a mix of histograms with exponential and custom buckets schemas for metric name "some_metric" # Should produce no results. +# histogram_count(rate()) must also warn when the schema mix falls inside the stats-only +# path (HistogramStatsIterator). Without Schema being set in that iterator, all histograms +# appear as Schema=0 and the custom-bucket mismatch is silently missed. +eval instant at 1m histogram_count(rate(some_metric[1m30s])) + expect warn msg: PromQL warning: vector contains a mix of histograms with exponential and custom buckets schemas for metric name "some_metric" + # Should produce no results. + # Start with custom, end with exponential. Return the exponential histogram divided by 48. # (The 1st sample is the NHCB with count:1. It is mostly ignored with the exception of the # count, which means the rate calculation extrapolates until the count hits 0.) From 73844c223fbb6bef34cd68ced277f5efc2ab2c37 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 10:20:11 +0000 Subject: [PATCH 034/170] Update module github.com/prometheus/prometheus to v0.311.3 [SECURITY] --- web/ui/mantine-ui/src/promql/tools/go.mod | 19 +------------------ web/ui/mantine-ui/src/promql/tools/go.sum | 6 +++--- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/web/ui/mantine-ui/src/promql/tools/go.mod b/web/ui/mantine-ui/src/promql/tools/go.mod index 7b9f818439..1f240d9aed 100644 --- a/web/ui/mantine-ui/src/promql/tools/go.mod +++ b/web/ui/mantine-ui/src/promql/tools/go.mod @@ -4,41 +4,24 @@ go 1.25.0 require ( github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 - github.com/prometheus/prometheus v0.309.1 + github.com/prometheus/prometheus v0.311.3 github.com/russross/blackfriday/v2 v2.1.0 ) require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 // indirect - github.com/aws/aws-sdk-go-v2 v1.41.4 // indirect - github.com/aws/aws-sdk-go-v2/config v1.32.12 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.19.12 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dennwc/varint v1.0.0 // indirect - github.com/golang-jwt/jwt/v5 v5.3.1 // indirect - github.com/klauspost/compress v1.18.5 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/prometheus/client_golang v1.23.2 // indirect - github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/procfs v0.16.1 // indirect - github.com/prometheus/sigv4 v0.4.1 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect - golang.org/x/net v0.52.0 // indirect - golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sys v0.42.0 // indirect golang.org/x/text v0.35.0 // indirect - google.golang.org/api v0.272.0 // indirect - google.golang.org/grpc v1.79.3 // indirect google.golang.org/protobuf v1.36.11 // indirect - k8s.io/client-go v0.35.3 // indirect - k8s.io/klog/v2 v2.140.0 // indirect ) replace cloud.google.com/go => cloud.google.com/go v0.123.0 diff --git a/web/ui/mantine-ui/src/promql/tools/go.sum b/web/ui/mantine-ui/src/promql/tools/go.sum index 2ef4300219..cd2e27d653 100644 --- a/web/ui/mantine-ui/src/promql/tools/go.sum +++ b/web/ui/mantine-ui/src/promql/tools/go.sum @@ -84,7 +84,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s= github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -103,8 +102,8 @@ github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEo github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= -github.com/prometheus/prometheus v0.309.1 h1:jutK6eCYDpWdPTUbVbkcQsNCMO9CCkSwjQRMLds4jSo= -github.com/prometheus/prometheus v0.309.1/go.mod h1:d+dOGiVhuNDa4MaFXHVdnUBy/CzqlcNTooR8oM1wdTU= +github.com/prometheus/prometheus v0.311.3 h1:3IrVxQv6v5i/ZCGi6OrYeBhtCwaPTn6Z3DYruXoYm3M= +github.com/prometheus/prometheus v0.311.3/go.mod h1:gjsCxTKtHO1Q8T9333u1s+lUR1OjPyM7ruuGH8RvVyo= github.com/prometheus/sigv4 v0.4.1 h1:EIc3j+8NBea9u1iV6O5ZAN8uvPq2xOIUPcqCTivHuXs= github.com/prometheus/sigv4 v0.4.1/go.mod h1:eu+ZbRvsc5TPiHwqh77OWuCnWK73IdkETYY46P4dXOU= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -157,6 +156,7 @@ k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8= k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= k8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg= k8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= From d36e9114cb75026c9715f76311539abcb3dafa00 Mon Sep 17 00:00:00 2001 From: bwplotka Date: Mon, 11 May 2026 12:10:00 +0100 Subject: [PATCH 035/170] chore: Upgrade Go deps Signed-off-by: bwplotka --- compliance/go.mod | 6 +- compliance/go.sum | 12 +- documentation/examples/remote_storage/go.mod | 134 +++--- documentation/examples/remote_storage/go.sum | 379 ++++++++--------- go.mod | 181 ++++---- go.sum | 416 +++++++++---------- internal/tools/go.mod | 39 +- internal/tools/go.sum | 100 ++--- web/ui/mantine-ui/src/promql/tools/go.mod | 15 +- web/ui/mantine-ui/src/promql/tools/go.sum | 128 +++--- 10 files changed, 713 insertions(+), 697 deletions(-) diff --git a/compliance/go.mod b/compliance/go.mod index 991b63f37a..018184c642 100644 --- a/compliance/go.mod +++ b/compliance/go.mod @@ -10,18 +10,18 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/snappy v1.0.0 // indirect github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 // indirect - github.com/klauspost/compress v1.18.5 // indirect + github.com/klauspost/compress v1.18.6 // indirect github.com/kr/text v0.2.0 // indirect github.com/oklog/run v1.2.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856 // indirect + github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/prometheus v0.307.4-0.20251119130332-1174b0ce4f1f // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/stretchr/testify v1.11.1 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - golang.org/x/text v0.35.0 // indirect + golang.org/x/text v0.37.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/compliance/go.sum b/compliance/go.sum index 38d8620144..0e4a9f3a33 100644 --- a/compliance/go.sum +++ b/compliance/go.sum @@ -13,8 +13,8 @@ github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 h1:cLN4IBkmkYZNnk7E github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= -github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= +github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -23,8 +23,8 @@ github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E= github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856 h1:1Y6bmpZb8peQCy1IpctnAhIFuyhrdtMaDnETChhSNns= -github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856/go.mod h1:Vf0QcmVhGqpjLxZOaWrFSep86vchQtJmbztFaMM4f6Q= +github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303 h1:PCg3CbvxfRdQOzkVLL6rdWJS2IkobPyAk7nouqiuA9c= +github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303/go.mod h1:vW/EVguzbNw6xMRmozJQWbY60/+Zsg0TgVJOSXGx2iI= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= @@ -58,8 +58,8 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= diff --git a/documentation/examples/remote_storage/go.mod b/documentation/examples/remote_storage/go.mod index e2bc55ae08..1767ab3f0a 100644 --- a/documentation/examples/remote_storage/go.mod +++ b/documentation/examples/remote_storage/go.mod @@ -14,72 +14,72 @@ require ( ) require ( - cloud.google.com/go/auth v0.18.2 // indirect + cloud.google.com/go/auth v0.20.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect - github.com/aws/aws-sdk-go-v2 v1.41.4 // indirect - github.com/aws/aws-sdk-go-v2/config v1.32.12 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.19.12 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect - github.com/aws/aws-sdk-go-v2/service/ec2 v1.296.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ecs v1.74.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 // indirect - github.com/aws/aws-sdk-go-v2/service/lightsail v1.51.0 // indirect - github.com/aws/aws-sdk-go-v2/service/signin v1.0.8 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.30.13 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 // indirect - github.com/aws/smithy-go v1.24.2 // indirect + github.com/aws/aws-sdk-go-v2 v1.41.7 // indirect + github.com/aws/aws-sdk-go-v2/config v1.32.17 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.16 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 // indirect + github.com/aws/aws-sdk-go-v2/service/ec2 v1.301.0 // indirect + github.com/aws/aws-sdk-go-v2/service/ecs v1.79.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 // indirect + github.com/aws/aws-sdk-go-v2/service/lightsail v1.53.2 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 // indirect + github.com/aws/smithy-go v1.25.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dennwc/varint v1.0.0 // indirect - github.com/digitalocean/godo v1.178.0 // indirect + github.com/digitalocean/godo v1.189.0 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/go-connections v0.6.0 // indirect - github.com/envoyproxy/go-control-plane/envoy v1.37.0 // indirect - github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect + github.com/docker/go-connections v0.7.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.10.1 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.5 // indirect - github.com/go-openapi/jsonreference v0.21.4 // indirect - github.com/go-openapi/swag v0.25.4 // indirect - github.com/go-openapi/swag/jsonname v0.25.5 // indirect + github.com/go-openapi/jsonpointer v0.23.1 // indirect + github.com/go-openapi/jsonreference v0.21.5 // indirect + github.com/go-openapi/swag v0.25.5 // indirect + github.com/go-openapi/swag/jsonname v0.26.0 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/golang-jwt/jwt/v5 v5.3.1 // indirect github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect - github.com/googleapis/gax-go/v2 v2.18.0 // indirect - github.com/gophercloud/gophercloud/v2 v2.11.1 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.15 // indirect + github.com/googleapis/gax-go/v2 v2.22.0 // indirect + github.com/gophercloud/gophercloud/v2 v2.12.0 // indirect github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 // indirect github.com/hashicorp/consul/api v1.32.1 // indirect - github.com/hashicorp/go-version v1.8.0 // indirect - github.com/hashicorp/nomad/api v0.0.0-20260324203407-b27b0c2e019a // indirect - github.com/hetznercloud/hcloud-go/v2 v2.36.0 // indirect + github.com/hashicorp/go-retryablehttp v0.7.8 // indirect + github.com/hashicorp/go-version v1.9.0 // indirect + github.com/hashicorp/nomad/api v0.0.0-20260508212055-068227ba803f // indirect + github.com/hetznercloud/hcloud-go/v2 v2.40.0 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect - github.com/ionos-cloud/sdk-go/v6 v6.3.6 // indirect + github.com/ionos-cloud/sdk-go/v6 v6.3.7 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.18.5 // indirect + github.com/klauspost/compress v1.18.6 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.3 // indirect + github.com/knadh/koanf/v2 v2.3.4 // indirect github.com/kylelemons/godebug v1.1.0 // indirect - github.com/linode/linodego v1.66.0 // indirect + github.com/linode/linodego v1.69.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/miekg/dns v1.1.72 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect @@ -89,53 +89,53 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/oapi-codegen/runtime v1.0.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.148.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.148.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.148.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.151.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.151.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.151.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856 // indirect + github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/otlptranslator v1.0.0 // indirect github.com/prometheus/procfs v0.16.1 // indirect github.com/prometheus/sigv4 v0.4.1 // indirect - github.com/puzpuzpuz/xsync/v4 v4.4.0 // indirect + github.com/puzpuzpuz/xsync/v4 v4.5.0 // indirect github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36 // indirect github.com/spf13/pflag v1.0.10 // indirect - github.com/stackitcloud/stackit-sdk-go/core v0.23.0 // indirect + github.com/stackitcloud/stackit-sdk-go/core v0.26.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/component v1.54.0 // indirect - go.opentelemetry.io/collector/confmap v1.54.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect - go.opentelemetry.io/collector/consumer v1.54.0 // indirect - go.opentelemetry.io/collector/featuregate v1.54.0 // indirect - go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect - go.opentelemetry.io/collector/pdata v1.54.0 // indirect - go.opentelemetry.io/collector/pipeline v1.54.0 // indirect - go.opentelemetry.io/collector/processor v1.54.0 // indirect + go.opentelemetry.io/collector/component v1.57.0 // indirect + go.opentelemetry.io/collector/confmap v1.57.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.151.0 // indirect + go.opentelemetry.io/collector/consumer v1.57.0 // indirect + go.opentelemetry.io/collector/featuregate v1.57.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.151.0 // indirect + go.opentelemetry.io/collector/pdata v1.57.0 // indirect + go.opentelemetry.io/collector/pipeline v1.57.0 // indirect + go.opentelemetry.io/collector/processor v1.57.0 // indirect go.opentelemetry.io/collector/semconv v0.128.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.67.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect - go.opentelemetry.io/otel v1.42.0 // indirect - go.opentelemetry.io/otel/metric v1.42.0 // indirect - go.opentelemetry.io/otel/trace v1.42.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.1 // indirect + go.uber.org/zap v1.28.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.49.0 // indirect - golang.org/x/net v0.52.0 // indirect + golang.org/x/crypto v0.50.0 // indirect + golang.org/x/net v0.53.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sys v0.42.0 // indirect - golang.org/x/text v0.35.0 // indirect + golang.org/x/sys v0.44.0 // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.15.0 // indirect - google.golang.org/api v0.272.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c // indirect - google.golang.org/grpc v1.79.3 // indirect + google.golang.org/api v0.278.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 // indirect + google.golang.org/grpc v1.81.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apimachinery v0.35.3 // indirect diff --git a/documentation/examples/remote_storage/go.sum b/documentation/examples/remote_storage/go.sum index cfebbcc786..27744423bc 100644 --- a/documentation/examples/remote_storage/go.sum +++ b/documentation/examples/remote_storage/go.sum @@ -1,17 +1,17 @@ -cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= -cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= +cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA= +cloud.google.com/go/auth v0.20.0/go.mod h1:942/yi/itH1SsmpyrbnTMDgGfdy2BUqIKyd0cyYLc5Q= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 h1:fou+2+WFTib47nS+nz/ozhEBnvU96bKHy6LjRsY4E28= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0/go.mod h1:t76Ruy8AHvUAC8GfMWJMa0ElSbuIcO03NLpynfbgsPA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 h1:jHb/wfvRikGdxMXYV3QG/SzUOPYN9KEUUuC0Yd0/vC0= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1/go.mod h1:pzBXCYn05zvYIrwLgtK8Ap8QcjRg+0i76tMQdWN6wOk= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6XuRW0nU7hgg4zlmZZa+a9q4= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 h1:bXwSugBiSbgtz7rOtbfGf+woewp4f06orW9OP5BjHLA= @@ -33,40 +33,40 @@ github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7D github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= -github.com/aws/aws-sdk-go-v2 v1.41.4 h1:10f50G7WyU02T56ox1wWXq+zTX9I1zxG46HYuG1hH/k= -github.com/aws/aws-sdk-go-v2 v1.41.4/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= -github.com/aws/aws-sdk-go-v2/config v1.32.12 h1:O3csC7HUGn2895eNrLytOJQdoL2xyJy0iYXhoZ1OmP0= -github.com/aws/aws-sdk-go-v2/config v1.32.12/go.mod h1:96zTvoOFR4FURjI+/5wY1vc1ABceROO4lWgWJuxgy0g= -github.com/aws/aws-sdk-go-v2/credentials v1.19.12 h1:oqtA6v+y5fZg//tcTWahyN9PEn5eDU/Wpvc2+kJ4aY8= -github.com/aws/aws-sdk-go-v2/credentials v1.19.12/go.mod h1:U3R1RtSHx6NB0DvEQFGyf/0sbrpJrluENHdPy1j/3TE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20 h1:zOgq3uezl5nznfoK3ODuqbhVg1JzAGDUhXOsU0IDCAo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20/go.mod h1:z/MVwUARehy6GAg/yQ1GO2IMl0k++cu1ohP9zo887wE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 h1:CNXO7mvgThFGqOFgbNAP2nol2qAWBOGfqR/7tQlvLmc= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20/go.mod h1:oydPDJKcfMhgfcgBUZaG+toBbwy8yPWubJXBVERtI4o= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 h1:tN6W/hg+pkM+tf9XDkWUbDEjGLb+raoBMFsTodcoYKw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20/go.mod h1:YJ898MhD067hSHA6xYCx5ts/jEd8BSOLtQDL3iZsvbc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.296.0 h1:98Miqj16un1WLNyM1RjVDhXYumhqZrQfAeG8i4jPG6o= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.296.0/go.mod h1:T6ndRfdhnXLIY5oKBHjYZDVj706los2zGdpThppquvA= -github.com/aws/aws-sdk-go-v2/service/ecs v1.74.0 h1:YS5TXaEvzDb+sV+wdQFUtuCAk0GeFR9Ai6HFdxpz6q8= -github.com/aws/aws-sdk-go-v2/service/ecs v1.74.0/go.mod h1:10kBgdaNJz0FO/+JWDUH+0rtSjkn5yafgavDDmmhFzs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 h1:2HvVAIq+YqgGotK6EkMf+KIEqTISmTYh5zLpYyeTo1Y= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20/go.mod h1:V4X406Y666khGa8ghKmphma/7C0DAtEQYhkq9z4vpbk= -github.com/aws/aws-sdk-go-v2/service/lightsail v1.51.0 h1:cg6PxzoIide2wiEyLfikOFN+XwHafwR8p5+L9U1E8dQ= -github.com/aws/aws-sdk-go-v2/service/lightsail v1.51.0/go.mod h1:YvX7hjUWecrKX8fBkbEncyddEW85xjNH+u5JHioITOw= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.8 h1:0GFOLzEbOyZABS3PhYfBIx2rNBACYcKty+XGkTgw1ow= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.8/go.mod h1:LXypKvk85AROkKhOG6/YEcHFPoX+prKTowKnVdcaIxE= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.13 h1:kiIDLZ005EcKomYYITtfsjn7dtOwHDOFy7IbPXKek2o= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.13/go.mod h1:2h/xGEowcW/g38g06g3KpRWDlT+OTfxxI0o1KqayAB8= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 h1:jzKAXIlhZhJbnYwHbvUQZEB8KfgAEuG0dc08Bkda7NU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17/go.mod h1:Al9fFsXjv4KfbzQHGe6V4NZSZQXecFcvaIF4e70FoRA= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 h1:Cng+OOwCHmFljXIxpEVXAGMnBia8MSU6Ch5i9PgBkcU= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.9/go.mod h1:LrlIndBDdjA/EeXeyNBle+gyCwTlizzW5ycgWnvIxkk= -github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= -github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/aws/aws-sdk-go-v2 v1.41.7 h1:DWpAJt66FmnnaRIOT/8ASTucrvuDPZASqhhLey6tLY8= +github.com/aws/aws-sdk-go-v2 v1.41.7/go.mod h1:4LAfZOPHNVNQEckOACQx60Y8pSRjIkNZQz1w92xpMJc= +github.com/aws/aws-sdk-go-v2/config v1.32.17 h1:FpL4/758/diKwqbytU0prpuiu60fgXKUWCpDJtApclU= +github.com/aws/aws-sdk-go-v2/config v1.32.17/go.mod h1:OXqUMzgXytfoF9JaKkhrOYsyh72t9G+MJH8mMRaexOE= +github.com/aws/aws-sdk-go-v2/credentials v1.19.16 h1:r3RJBuU7X9ibt8RHbMjWE6y60QbKBiII6wSrXnapxSU= +github.com/aws/aws-sdk-go-v2/credentials v1.19.16/go.mod h1:6cx7zqDENJDbBIIWX6P8s0h6hqHC8Avbjh9Dseo27ug= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 h1:UuSfcORqNSz/ey3VPRS8TcVH2Ikf0/sC+Hdj400QI6U= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23/go.mod h1:+G/OSGiOFnSOkYloKj/9M35s74LgVAdJBSD5lsFfqKg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 h1:GpT/TrnBYuE5gan2cZbTtvP+JlHsutdmlV2YfEyNde0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23/go.mod h1:xYWD6BS9ywC5bS3sz9Xh04whO/hzK2plt2Zkyrp4JuA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 h1:bpd8vxhlQi2r1hiueOw02f/duEPTMK59Q4QMAoTTtTo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23/go.mod h1:15DfR2nw+CRHIk0tqNyifu3G1YdAOy68RftkhMDDwYk= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 h1:OQqn11BtaYv1WLUowvcA30MpzIu8Ti4pcLPIIyoKZrA= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24/go.mod h1:X5ZJyfwVrWA96GzPmUCWFQaEARPR7gCrpq2E92PJwAE= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.301.0 h1:U+cZAMc8mN0jne8/ae7KrrFuILTXrZReAvc6BIpXGls= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.301.0/go.mod h1:Y95W0Hm6FYLPa6o0hbnJ+sWgmdc4ifcLFjGkdobWVhY= +github.com/aws/aws-sdk-go-v2/service/ecs v1.79.1 h1:tQNU4tC4cMoZo1e+7J8j3/GWM7PJFdXCN0VzEFwFqUE= +github.com/aws/aws-sdk-go-v2/service/ecs v1.79.1/go.mod h1:TIKZ9zIFS6W2k9FeW+r5sGVnlxp+aUt9oQ/St3Suj1o= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 h1:FLudkZLt5ci0ozzgkVo8BJGwvqNaZbTWb3UcucAateA= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9/go.mod h1:w7wZ/s9qK7c8g4al+UyoF1Sp/Z45UwMGcqIzLWVQHWk= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 h1:pbrxO/kuIwgEsOPLkaHu0O+m4fNgLU8B3vxQ+72jTPw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23/go.mod h1:/CMNUqoj46HpS3MNRDEDIwcgEnrtZlKRaHNaHxIFpNA= +github.com/aws/aws-sdk-go-v2/service/lightsail v1.53.2 h1:frwYj+OqTr28EO/GFxuE9fsjOF/7WIOrklzusnV4Kzw= +github.com/aws/aws-sdk-go-v2/service/lightsail v1.53.2/go.mod h1:Etcg8xorq1b0g0V2KMNgFjubYITZseJv08qtX/3szko= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 h1:TdJ+HdzOBhU8+iVAOGUTU63VXopcumCOF1paFulHWZc= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.11/go.mod h1:R82ZRExE/nheo0N+T8zHPcLRTcH8MGsnR3BiVGX0TwI= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 h1:7byT8HUWrgoRp6sXjxtZwgOKfhss5fW6SkLBtqzgRoE= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.17/go.mod h1:xNWknVi4Ezm1vg1QsB/5EWpAJURq22uqd38U8qKvOJc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21 h1:+1Kl1zx6bWi4X7cKi3VYh29h8BvsCoHQEQ6ST9X8w7w= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21/go.mod h1:4vIRDq+CJB2xFAXZ+YgGUTiEft7oAQlhIs71xcSeuVg= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 h1:F/M5Y9I3nwr2IEpshZgh1GeHpOItExNM9L1euNuh/fk= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.1/go.mod h1:mTNxImtovCOEEuD65mKW7DCsL+2gjEH+RPEAexAzAio= +github.com/aws/smithy-go v1.25.1 h1:J8ERsGSU7d+aCmdQur5Txg6bVoYelvQJgtZehD12GkI= +github.com/aws/smithy-go v1.25.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3/go.mod h1:CIWtjkly68+yqLPbvwwR/fjNJA/idrtULjZWh2v1ys0= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -74,8 +74,8 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= -github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= @@ -86,20 +86,21 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= -github.com/digitalocean/godo v1.178.0 h1:+B4xGOaoFwwwpM7TKhoyGHdmFg5eF9zDB1YfOLvNJ2E= -github.com/digitalocean/godo v1.178.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU= +github.com/digitalocean/godo v1.189.0 h1:93hHWsZdbJdkMsfZ21lMkOmd+BPMCTzu/+FIJ5FvAL4= +github.com/digitalocean/godo v1.189.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM= github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= -github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= +github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c= +github.com/docker/go-connections v0.7.0/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84= github.com/edsrzf/mmap-go v1.2.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA= github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ= github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A= github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds= @@ -110,8 +111,8 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= +github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -119,34 +120,34 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= -github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0= -github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= -github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= -github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= -github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= -github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= -github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= -github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= -github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= -github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= -github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= -github.com/go-openapi/swag/jsonname v0.25.5 h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo= -github.com/go-openapi/swag/jsonname v0.25.5/go.mod h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU= -github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= -github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= -github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= -github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= -github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= -github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= -github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= -github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= -github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= -github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= -github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= -github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= -github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= -github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= +github.com/go-openapi/jsonpointer v0.23.1 h1:1HBACs7XIwR2RcmItfdSFlALhGbe6S92p0ry4d1GWg4= +github.com/go-openapi/jsonpointer v0.23.1/go.mod h1:iWRmZTrGn7XwYhtPt/fvdSFj1OfNBngqRT2UG3BxSqY= +github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= +github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= +github.com/go-openapi/swag v0.25.5 h1:pNkwbUEeGwMtcgxDr+2GBPAk4kT+kJ+AaB+TMKAg+TU= +github.com/go-openapi/swag v0.25.5/go.mod h1:B3RT6l8q7X803JRxa2e59tHOiZlX1t8viplOcs9CwTA= +github.com/go-openapi/swag/cmdutils v0.25.5 h1:yh5hHrpgsw4NwM9KAEtaDTXILYzdXh/I8Whhx9hKj7c= +github.com/go-openapi/swag/cmdutils v0.25.5/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.5 h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+tGu97g= +github.com/go-openapi/swag/conv v0.25.5/go.mod h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k= +github.com/go-openapi/swag/fileutils v0.25.5 h1:B6JTdOcs2c0dBIs9HnkyTW+5gC+8NIhVBUwERkFhMWk= +github.com/go-openapi/swag/fileutils v0.25.5/go.mod h1:V3cT9UdMQIaH4WiTrUc9EPtVA4txS0TOmRURmhGF4kc= +github.com/go-openapi/swag/jsonname v0.26.0 h1:gV1NFX9M8avo0YSpmWogqfQISigCmpaiNci8cGECU5w= +github.com/go-openapi/swag/jsonname v0.26.0/go.mod h1:urBBR8bZNoDYGr653ynhIx+gTeIz0ARZxHkAPktJK2M= +github.com/go-openapi/swag/jsonutils v0.25.5 h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo= +github.com/go-openapi/swag/jsonutils v0.25.5/go.mod h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4= +github.com/go-openapi/swag/loading v0.25.5 h1:odQ/umlIZ1ZVRteI6ckSrvP6e2w9UTF5qgNdemJHjuU= +github.com/go-openapi/swag/loading v0.25.5/go.mod h1:I8A8RaaQ4DApxhPSWLNYWh9NvmX2YKMoB9nwvv6oW6g= +github.com/go-openapi/swag/mangling v0.25.5 h1:hyrnvbQRS7vKePQPHHDso+k6CGn5ZBs5232UqWZmJZw= +github.com/go-openapi/swag/mangling v0.25.5/go.mod h1:6hadXM/o312N/h98RwByLg088U61TPGiltQn71Iw0NY= +github.com/go-openapi/swag/netutils v0.25.5 h1:LZq2Xc2QI8+7838elRAaPCeqJnHODfSyOa7ZGfxDKlU= +github.com/go-openapi/swag/netutils v0.25.5/go.mod h1:lHbtmj4m57APG/8H7ZcMMSWzNqIQcu0RFiXrPUara14= +github.com/go-openapi/swag/stringutils v0.25.5 h1:NVkoDOA8YBgtAR/zvCx5rhJKtZF3IzXcDdwOsYzrB6M= +github.com/go-openapi/swag/stringutils v0.25.5/go.mod h1:PKK8EZdu4QJq8iezt17HM8RXnLAzY7gW0O1KKarrZII= +github.com/go-openapi/swag/typeutils v0.25.5 h1:EFJ+PCga2HfHGdo8s8VJXEVbeXRCYwzzr9u4rJk7L7E= +github.com/go-openapi/swag/typeutils v0.25.5/go.mod h1:itmFmScAYE1bSD8C4rS0W+0InZUBrB2xSPbWt6DLGuc= +github.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT6G0iq2SSbVQ= +github.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ= github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk= github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= @@ -174,12 +175,12 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8= -github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= -github.com/googleapis/gax-go/v2 v2.18.0 h1:jxP5Uuo3bxm3M6gGtV94P4lliVetoCB4Wk2x8QA86LI= -github.com/googleapis/gax-go/v2 v2.18.0/go.mod h1:uSzZN4a356eRG985CzJ3WfbFSpqkLTjsnhWGJR6EwrE= -github.com/gophercloud/gophercloud/v2 v2.11.1 h1:jCs4vLH8sJgRqrPzqVfWgl7uI6JnIIlsgeIRM0uHjxY= -github.com/gophercloud/gophercloud/v2 v2.11.1/go.mod h1:Rm0YvKQ4QYX2rY9XaDKnjRzSGwlG5ge4h6ABYnmkKQM= +github.com/googleapis/enterprise-certificate-proxy v0.3.15 h1:xolVQTEXusUcAA5UgtyRLjelpFFHWlPQ4XfWGc7MBas= +github.com/googleapis/enterprise-certificate-proxy v0.3.15/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= +github.com/googleapis/gax-go/v2 v2.22.0 h1:PjIWBpgGIVKGoCXuiCoP64altEJCj3/Ei+kSU5vlZD4= +github.com/googleapis/gax-go/v2 v2.22.0/go.mod h1:irWBbALSr0Sk3qlqb9SyJ1h68WjgeFuiOzI4Rqw5+aY= +github.com/gophercloud/gophercloud/v2 v2.12.0 h1:Gxmc/Bog1UDKkxTcQW7MSPTDviJXpLeEgVeN5KrxoCo= +github.com/gophercloud/gophercloud/v2 v2.12.0/go.mod h1:H7TTOxbLy8RIaHSNhI2GCrWIzw4Xpw8Xn2mBhCUT5kA= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 h1:cLN4IBkmkYZNnk7EAJ0BHIethd+J6LqxFNw5mSiI2bM= @@ -198,26 +199,26 @@ github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJ github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= -github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-retryablehttp v0.7.8 h1:ylXZWnqa7Lhqpk0L1P1LzDtGcCR0rPVUrx/c8Unxc48= +github.com/hashicorp/go-retryablehttp v0.7.8/go.mod h1:rjiScheydd+CxvumBsIrFKlx3iS0jrZ7LvzFGFmuKbw= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= -github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA= +github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/nomad/api v0.0.0-20260324203407-b27b0c2e019a h1:HGwfgBNl90YBiHdbzZ/+8aMxO1UL9B/yNTAXa8iB8z8= -github.com/hashicorp/nomad/api v0.0.0-20260324203407-b27b0c2e019a/go.mod h1:KkLNLU0Nyfh5jWsFoF/PsmMbKpRIAoIV4lmQoJWgKCk= +github.com/hashicorp/nomad/api v0.0.0-20260508212055-068227ba803f h1:T3PgfZZqrpDWAKQGk1SDC23LgK+ac42u66WrzymA8Zg= +github.com/hashicorp/nomad/api v0.0.0-20260508212055-068227ba803f/go.mod h1:KkLNLU0Nyfh5jWsFoF/PsmMbKpRIAoIV4lmQoJWgKCk= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hetznercloud/hcloud-go/v2 v2.36.0 h1:HlLL/aaVXUulqe+rsjoJmrxKhPi1MflL5O9iq5QEtvo= -github.com/hetznercloud/hcloud-go/v2 v2.36.0/go.mod h1:MnN/QJEa/RYNQiiVoJjNHPntM7Z1wlYPgJ2HA40/cDE= +github.com/hetznercloud/hcloud-go/v2 v2.40.0 h1:fuP7khfiDQAIXdKyQq7f3LnnOjyZg0PXTafXjUKkqIA= +github.com/hetznercloud/hcloud-go/v2 v2.40.0/go.mod h1:ANz38eerXjPv00dm9dckKhttOGtYeeGmjjvwL5e6c5E= github.com/influxdata/influxdb-client-go/v2 v2.14.0 h1:AjbBfJuq+QoaXNcrova8smSjwJdUHnwvfjMF71M1iI4= github.com/influxdata/influxdb-client-go/v2 v2.14.0/go.mod h1:Ahpm3QXKMJslpXl3IftVLVezreAUtBOTZssDrjZEFHI= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= -github.com/ionos-cloud/sdk-go/v6 v6.3.6 h1:l/TtKgdQ1wUH3DDe2SfFD78AW+TJWdEbDpQhHkWd6CM= -github.com/ionos-cloud/sdk-go/v6 v6.3.6/go.mod h1:nUGHP4kZHAZngCVr4v6C8nuargFrtvt7GrzH/hqn7c4= +github.com/ionos-cloud/sdk-go/v6 v6.3.7 h1:t773JkC/asnyVqeQ+OvN9WCRZuosSoPtJfyM82EFCWY= +github.com/ionos-cloud/sdk-go/v6 v6.3.7/go.mod h1:nUGHP4kZHAZngCVr4v6C8nuargFrtvt7GrzH/hqn7c4= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -227,14 +228,14 @@ github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRt github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= -github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= +github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= -github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.4 h1:fnynNSDlujWE+v83hAp8wKr/cdoxHLO0629SN+U8Urc= +github.com/knadh/koanf/v2 v2.3.4/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -243,8 +244,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/linode/linodego v1.66.0 h1:rK8QJFaV53LWOEJvb/evhTg/dP5ElvtuZmx4iv4RJds= -github.com/linode/linodego v1.66.0/go.mod h1:12ykGs9qsvxE+OU3SXuW2w+DTruWF35FPlXC7gGk2tU= +github.com/linode/linodego v1.69.0 h1:5Qsv6kwoTwwOBETfgietEg5UcaKg1bQEN0DDYc2wIeM= +github.com/linode/linodego v1.69.0/go.mod h1:QPzvRKCy9oz1lRaIACPRORoAI9AAfKKg2AR5mXujoB0= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -276,12 +277,12 @@ github.com/oapi-codegen/runtime v1.0.0/go.mod h1:LmCUMQuPB4M/nLXilQXhHw+BLZdDb18 github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s= github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.148.0 h1:CiTjQE/Hh5xK2t56ogrDK4nl0+tJPNmASCs4zEYZ/xU= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.148.0/go.mod h1:WUFkzTiOpt7EYyL67gv1GOf3RD8qKWGtin3lY9LYzW4= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.148.0 h1:1TLg6YrS3Au6F7xw3ws2Njbwj13IMqPplvGFi+18fWs= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.148.0/go.mod h1:P8hZEDIQk4REgUWyLhSVRHwTxK6KkifKfg36BmmQ/DI= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.148.0 h1:xgD/kNGp/wWY+bwY599Pc01OamYN17phRiTP934bM5Y= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.148.0/go.mod h1:ZK7wvaefla9lB3bAW0rNKt7IzRPcTRQoOFqr4sZy/XM= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.151.0 h1:RAnPnD3DcYVzd+BbPGtauEsy86BCjSa+SEykD6y3oKo= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.151.0/go.mod h1:B2rs2x914jqvMApxRWs8R/fjtnJFy6Ml8bnaZHChKVQ= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.151.0 h1:c8+upXGwDxokINkuChSD7INYHlpcCAyQs2aXpx4rzSs= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.151.0/go.mod h1:Ln3K9yJgPAwEUXqCoR8htVs6bk3cyj6zIPOyM/LhiPo= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.151.0 h1:ba6grxqvfpW4++JoP/dlOk6oV2g88DJ2wBQ+yTVyshQ= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.151.0/go.mod h1:oUwKfAyARk9N1m+ZndqDepHIGyFBTubitsnVqWKcLNs= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -299,8 +300,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= -github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856 h1:1Y6bmpZb8peQCy1IpctnAhIFuyhrdtMaDnETChhSNns= -github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856/go.mod h1:Vf0QcmVhGqpjLxZOaWrFSep86vchQtJmbztFaMM4f6Q= +github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303 h1:PCg3CbvxfRdQOzkVLL6rdWJS2IkobPyAk7nouqiuA9c= +github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303/go.mod h1:vW/EVguzbNw6xMRmozJQWbY60/+Zsg0TgVJOSXGx2iI= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= @@ -313,8 +314,8 @@ github.com/prometheus/prometheus v0.308.1 h1:ApMNI/3/es3Ze90Z7CMb+wwU2BsSYur0m5V github.com/prometheus/prometheus v0.308.1/go.mod h1:aHjYCDz9zKRyoUXvMWvu13K9XHOkBB12XrEqibs3e0A= github.com/prometheus/sigv4 v0.4.1 h1:EIc3j+8NBea9u1iV6O5ZAN8uvPq2xOIUPcqCTivHuXs= github.com/prometheus/sigv4 v0.4.1/go.mod h1:eu+ZbRvsc5TPiHwqh77OWuCnWK73IdkETYY46P4dXOU= -github.com/puzpuzpuz/xsync/v4 v4.4.0 h1:vlSN6/CkEY0pY8KaB0yqo/pCLZvp9nhdbBdjipT4gWo= -github.com/puzpuzpuz/xsync/v4 v4.4.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo= +github.com/puzpuzpuz/xsync/v4 v4.5.0 h1:vOSWu6b57/emh+L/Cw0BeQfvxa/cogFywXHeGUxQxAg= +github.com/puzpuzpuz/xsync/v4 v4.5.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36 h1:ObX9hZmK+VmijreZO/8x9pQ8/P/ToHD/bdSb4Eg4tUo= @@ -322,8 +323,8 @@ github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36/go.mod h1:LEsDu4BubxK7/cWhtlQ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= -github.com/stackitcloud/stackit-sdk-go/core v0.23.0 h1:zPrOhf3Xe47rKRs1fg/AqKYUiJJRYjdcv+3qsS50mEs= -github.com/stackitcloud/stackit-sdk-go/core v0.23.0/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI= +github.com/stackitcloud/stackit-sdk-go/core v0.26.0 h1:jQEb9gkehfp6VCP6TcYk7BI10cz4l0KM2L6hqYBH2QA= +github.com/stackitcloud/stackit-sdk-go/core v0.26.0/go.mod h1:WU1hhxnjXw2EV7CYa1nlEvNpMiRY6CvmIOaHuL3pOaA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -346,58 +347,58 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/collector/component v1.54.0 h1:LvtX0Tzz18n44OrUFVk77N1FNsejfWJqztB28hrmDM8= -go.opentelemetry.io/collector/component v1.54.0/go.mod h1:yUMBYsySY/sDcXm8kOzEoZxt+JLdala6hxzSW0npOxY= -go.opentelemetry.io/collector/component/componentstatus v0.148.0 h1:sCGRaXNQolHFhPjrNJEwQ1WZOf96iL99tzm9GxuZsvg= -go.opentelemetry.io/collector/component/componentstatus v0.148.0/go.mod h1:yqg3SpGQc22W3wGICdnb+2kZVW9daBr3+LrGUCHkKfc= -go.opentelemetry.io/collector/component/componenttest v0.148.0 h1:tBXJWmy2X6KD8S0QU2YZa2zYBqP+IycSM4iOtwDD2pA= -go.opentelemetry.io/collector/component/componenttest v0.148.0/go.mod h1:1c1+6mZOmI0raoya5vA/X0F+fawEjNS6tCEs5xLATtA= -go.opentelemetry.io/collector/confmap v1.54.0 h1:RUoxQ4uAYHTI57GfHh61D00tTQsXm9T88ozrAiicByc= -go.opentelemetry.io/collector/confmap v1.54.0/go.mod h1:mQxG8bk0IWIt9gbWMvzE+cRkOuCuzbzkNGBq2YJ4wNM= -go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 h1:UW8MX5VlKJf67x4Et7J9kPwP9Rv4VSmJ+UUpgRcb//c= -go.opentelemetry.io/collector/confmap/xconfmap v0.148.0/go.mod h1:4qTMr3V0uSXXac9wVs/UD5fIqRKw5yIl58+Vjsc6RHM= -go.opentelemetry.io/collector/consumer v1.54.0 h1:RGGtUN+GbkV1px3T6XdUHmgJ+ldJ1hAHdesFzW/wgL0= -go.opentelemetry.io/collector/consumer v1.54.0/go.mod h1:1PC6XINTL9DdT1bwvfMdHE72EB4RWU/WcPemUrhqKN8= -go.opentelemetry.io/collector/consumer/consumertest v0.148.0 h1:ms0HtWMj17tI1Yds0hSuUI5QYpNEqd11AAhwIoUY2HE= -go.opentelemetry.io/collector/consumer/consumertest v0.148.0/go.mod h1:wScw/OzKkf/ZzJn4ToI30OoI1kJiY16WNrcFToXSzK0= -go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 h1:m3b9rY7CLD5Pcge6sSKHIT3OlcPN6xqYsdtVs9oJ528= -go.opentelemetry.io/collector/consumer/xconsumer v0.148.0/go.mod h1:bG+Wz6xmIBl/gHzq1sqvksWXqTLuTX17Wo//zIsdZpw= -go.opentelemetry.io/collector/featuregate v1.54.0 h1:ufo5Hy4Co9pcHVg24hyanm8qFG3TkkYbVyQXPVAbwDc= -go.opentelemetry.io/collector/featuregate v1.54.0/go.mod h1:PS7zY/zaCb28EqciePVwRHVhc3oKortTFXsi3I6ee4g= -go.opentelemetry.io/collector/internal/componentalias v0.148.0 h1:Y6MftNIZSzOr47TTj6A2z2UR3IwbeG46sAQshicGtDg= -go.opentelemetry.io/collector/internal/componentalias v0.148.0/go.mod h1:uwKzfehzwRgHxdHgFXYSBHNBeWSSqsqQYGWr5fk08G0= -go.opentelemetry.io/collector/internal/testutil v0.148.0 h1:3Z9hperte3vSmbBTYeNndoEUICICrNz8hzx+v0FYXBQ= -go.opentelemetry.io/collector/internal/testutil v0.148.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= -go.opentelemetry.io/collector/pdata v1.54.0 h1:3LharKb792cQ3VrUGxd3IcpWwfu3ST+GSTU382jVz1s= -go.opentelemetry.io/collector/pdata v1.54.0/go.mod h1:+MqC3VVOv/EX9YVFUo+mI4F0YmwJ+fXBYwjmu+mRiZ8= -go.opentelemetry.io/collector/pdata/pprofile v0.148.0 h1:MgrNZmqwhZGfiYwcKKtM/iXgTZqqvG5dUphriRXMZHU= -go.opentelemetry.io/collector/pdata/pprofile v0.148.0/go.mod h1:MTTMnZPqWX1S/rBDatU0W19udlycBkWuzVV5qnemHdc= -go.opentelemetry.io/collector/pdata/testdata v0.148.0 h1:yzakPuFgoKK8WcrlhyYHLMLA/kLScQKGsXkIgwieAQ8= -go.opentelemetry.io/collector/pdata/testdata v0.148.0/go.mod h1:2rFvxm8qwd3nlO90FtJw6ZGAjt+bLndxmQuJaMO9kfQ= -go.opentelemetry.io/collector/pipeline v1.54.0 h1:jYlCkdFLITVBdeB+IGS07zXWywEgvT3Ky46vdKKT+Ks= -go.opentelemetry.io/collector/pipeline v1.54.0/go.mod h1:RD90NG3Jbk965Xaqym3JyHkuol4uZJjQVUkD9ddXJIs= -go.opentelemetry.io/collector/processor v1.54.0 h1:zmHBFiEFmU9ZYuHhVP3lHIkbfy+ueapzGpTdXVMcWBg= -go.opentelemetry.io/collector/processor v1.54.0/go.mod h1:L0lA6DZ0VbrtQBg44cmYfSpRlgm4zxW1I6QfBnRizPw= -go.opentelemetry.io/collector/processor/processortest v0.148.0 h1:p0k59frZxy/Z4fXe82i5eOJv/UyOH75XhI8nFD1ZWCE= -go.opentelemetry.io/collector/processor/processortest v0.148.0/go.mod h1:E2Li2gnkUXgvApvGyEtn3Eq5KyzV05ljfbFRsZ7sTC4= -go.opentelemetry.io/collector/processor/xprocessor v0.148.0 h1:v7Qv6k2b2cvgGWuTO5KN5QYDLl1r5sznt7Le4Fhpa4c= -go.opentelemetry.io/collector/processor/xprocessor v0.148.0/go.mod h1:r7ADpSX2nf0rZR9STxh956Qw1740QOWMXLnEM/ZiaF8= +go.opentelemetry.io/collector/component v1.57.0 h1:WKIqx2Bs0JaAZxDEhsLradXpYxnwAxVFzWhQUmu2q3w= +go.opentelemetry.io/collector/component v1.57.0/go.mod h1:rXLy5mV78e7Gqp/dzFB+nbAFSEuJCipJfp8LbkrvOMg= +go.opentelemetry.io/collector/component/componentstatus v0.151.0 h1:S2L2y/r+MrqSR8CG/SpbN4WbbUQC5sK+1VgBR2rN660= +go.opentelemetry.io/collector/component/componentstatus v0.151.0/go.mod h1:cDj64a2MAE/pWA1x/jR+oYZQ0d4LBYHcxxONYuijREE= +go.opentelemetry.io/collector/component/componenttest v0.151.0 h1:0rYcx913VAfD1VyVA9MKPjTrdinUaJGEaOhom8MX5zY= +go.opentelemetry.io/collector/component/componenttest v0.151.0/go.mod h1:vmhG58+J9QHOHaNu8LUD5d13LqldvkzI2jil4+lk+x0= +go.opentelemetry.io/collector/confmap v1.57.0 h1:5AuK920dJmV8zxQAiODi2JHPl2r1HmEHHMaBSC+qF5I= +go.opentelemetry.io/collector/confmap v1.57.0/go.mod h1:ifmog4kqEMM037qX04qEbom5CcxhmkadLUqhi2Vkuec= +go.opentelemetry.io/collector/confmap/xconfmap v0.151.0 h1:txpp8lH/J2sKsQXEmV0TXTIrDS7n0Bo2bPJR+mhcP3M= +go.opentelemetry.io/collector/confmap/xconfmap v0.151.0/go.mod h1:3R0Ru3Gsz6HKzjMecZPlTFDzFxaxAOl23ptm+xlsAA0= +go.opentelemetry.io/collector/consumer v1.57.0 h1:jyDh4GkYPuIXNB0UJIh33NAzZoTCVNkwS+XWdlI08P8= +go.opentelemetry.io/collector/consumer v1.57.0/go.mod h1:tJKbog9Xw/8y66aWd/C+21BMuQkOWn/lF4bzJDRC9OM= +go.opentelemetry.io/collector/consumer/consumertest v0.151.0 h1:qByIVlFh9RAR/newAk/sN5i1zoIXKa2K1hRNVfye8LU= +go.opentelemetry.io/collector/consumer/consumertest v0.151.0/go.mod h1:eAGCGxkq+aABLmlr3PvMOqz3ZJbmn/lUqCbbffabSi4= +go.opentelemetry.io/collector/consumer/xconsumer v0.151.0 h1:eKIYxuPBEIrjZMAkyKBUWrlpHAE9OgxXBjq7PMSeXkE= +go.opentelemetry.io/collector/consumer/xconsumer v0.151.0/go.mod h1:9K97TkCN7XYfwKzPzktozrWc3Qw/4A1T4XgMn9TnG0c= +go.opentelemetry.io/collector/featuregate v1.57.0 h1:KPDSUKYn6MHwgyGRSGPPcW/G96HH93pxuvvPwM+R8nY= +go.opentelemetry.io/collector/featuregate v1.57.0/go.mod h1:4ga1QBMPEejXXmpyJS8lmaRpknJ3Lb9Bvk6e420bUFU= +go.opentelemetry.io/collector/internal/componentalias v0.151.0 h1:5IJn4XXRbjGrJCuIByHzxgHqwC0Hcl99tM+PoyYzjJY= +go.opentelemetry.io/collector/internal/componentalias v0.151.0/go.mod h1:c70sQuXHQZWSYCyc0y/VynqJdmEeBunSmEy3xfLQPWE= +go.opentelemetry.io/collector/internal/testutil v0.151.0 h1:CFjDItLuqzblItOsnK6IPSdrsOaZCaDjYpB8qWG+XHI= +go.opentelemetry.io/collector/internal/testutil v0.151.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= +go.opentelemetry.io/collector/pdata v1.57.0 h1:oDWBMjEIqyJO3GJEB+iwqxj47rxDK19OKzwaFEaE4sg= +go.opentelemetry.io/collector/pdata v1.57.0/go.mod h1:wZojinP6mNhLXudH8QXx/bjWzOsKMxi/FXwnk+12G/w= +go.opentelemetry.io/collector/pdata/pprofile v0.151.0 h1:hsU0+DpkvhJh3xL1Y8CX2vAPdLMoJLiw+C+rAMsaxZc= +go.opentelemetry.io/collector/pdata/pprofile v0.151.0/go.mod h1:5zfGTQqRuaKyh2SRaZi4SV4nSD8TzY1kYoOjniOD3uk= +go.opentelemetry.io/collector/pdata/testdata v0.151.0 h1:ye09e8UMADdVrQjLgCznZxmM8ra7ciAuOCteHDzgHjc= +go.opentelemetry.io/collector/pdata/testdata v0.151.0/go.mod h1:h5+Ys9F+pf64cGt5cZCDtRsrkOnvjgpcONr8pFA3KBc= +go.opentelemetry.io/collector/pipeline v1.57.0 h1:nlevGN75Vt/Fp0HTaDjZpUHQf5QFA6o2asSmzSoBVkA= +go.opentelemetry.io/collector/pipeline v1.57.0/go.mod h1:RD90NG3Jbk965Xaqym3JyHkuol4uZJjQVUkD9ddXJIs= +go.opentelemetry.io/collector/processor v1.57.0 h1:EyW3f4pvt/gsfM3JKgRn2WZEyknGzZk5TES3FmwNLgg= +go.opentelemetry.io/collector/processor v1.57.0/go.mod h1:EdKVhK9Oj8Cj2EdYqD/rDKdklLcdwpfSM/q6+KZOMbc= +go.opentelemetry.io/collector/processor/processortest v0.151.0 h1:J+7wLfpyO+gE/yfct11Sy1F6e+/KkLe1/gnh6jDbvbE= +go.opentelemetry.io/collector/processor/processortest v0.151.0/go.mod h1:SKl5FdxTH4bsi90E8e1W79Q94Uoh+OfEMq7yoZqUYVE= +go.opentelemetry.io/collector/processor/xprocessor v0.151.0 h1:TQhnUOP1vbdQ7zKD7SXfjtpthnfwWg23r8a6yeXDN84= +go.opentelemetry.io/collector/processor/xprocessor v0.151.0/go.mod h1:36fKMHBSieF/Se9ErxfNJkMP40IkwerFcuVwG8oF/n0= go.opentelemetry.io/collector/semconv v0.128.0 h1:MzYOz7Vgb3Kf5D7b49pqqgeUhEmOCuT10bIXb/Cc+k4= go.opentelemetry.io/collector/semconv v0.128.0/go.mod h1:OPXer4l43X23cnjLXIZnRj/qQOjSuq4TgBLI76P9hns= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.67.0 h1:c9r/G1CSw4dPI1jaNNG9RnQP+q4SvZnHciDQJVIvchU= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.67.0/go.mod h1:gO9smoZe9KnZcJCqcB0lMmQ4Z5VEifYmjMTpnwtTSuQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0 h1:cuXaPAfIoJKsYjBjPSb2nKZEmgM43zVr25l37IxhKME= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0/go.mod h1:BuzhPofpCzlDi/Q/Xjg54M4/3oWqqyDe2Zeq7A2I0QE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 h1:CqXxU8VOmDefoh0+ztfGaymYbhdB/tT3zs79QaZTNGY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0/go.mod h1:BuhAPThV8PBHBvg8ZzZ/Ok3idOdhWIodywz2xEcRbJo= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= @@ -410,8 +411,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= -go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= +go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= @@ -419,20 +420,20 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= golang.org/x/exp v0.0.0-20250808145144-a408d31f581a h1:Y+7uR/b1Mw2iSXZ3G//1haIiSElDQZ8KWh0h+sZPG90= golang.org/x/exp v0.0.0-20250808145144-a408d31f581a/go.mod h1:rT6SFzZ7oxADUDx58pcaKFTcZ+inxAa9fTrYx/uVYwg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -444,36 +445,38 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.272.0 h1:eLUQZGnAS3OHn31URRf9sAmRk3w2JjMx37d2k8AjJmA= -google.golang.org/api v0.272.0/go.mod h1:wKjowi5LNJc5qarNvDCvNQBn3rVK8nSy6jg2SwRwzIA= -google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI= -google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c h1:xgCzyF2LFIO/0X2UAoVRiXKU5Xg6VjToG4i2/ecSswk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/api v0.278.0 h1:W7jiRvRi53VYFfZ/HoZjQBtJk7gOFbHD8ot1RzVZU6E= +google.golang.org/api v0.278.0/go.mod h1:B9TqLBwJqVjp1mtt7WeoQwWRwvu/400y5lETOql+giQ= +google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0= +google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= +google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348 h1:U8orV30l6KpDsi9dxU0CoJZGbjS8EEpw+6ba+XwGPQA= +google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348/go.mod h1:Yzdzr5OOZFgSsEV2D/Xi9NL3bszpXFAg0hFJiRohcD8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 h1:tEkOQcXgF6dH1G+MVKZrfpYvozGrzb91k6ha7jireSM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw= +google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -483,8 +486,8 @@ gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnf gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.67.1 h1:tVBILHy0R6e4wkYOn3XmiITt/hEVH4TFMYvAX2Ytz6k= -gopkg.in/ini.v1 v1.67.1/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= +gopkg.in/ini.v1 v1.67.2 h1:JtOSMb9OuaCZKr7h5D/h6iii14sK0hLbplTc6frx4Ss= +gopkg.in/ini.v1 v1.67.2/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/go.mod b/go.mod index b5bb9d1836..dad5385ba9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/prometheus/prometheus go 1.25.0 require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4 v4.3.0 @@ -11,83 +11,83 @@ require ( github.com/KimMachineGun/automemlimit v0.7.5 github.com/alecthomas/kingpin/v2 v2.4.0 github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b - github.com/aws/aws-sdk-go-v2 v1.41.4 - github.com/aws/aws-sdk-go-v2/config v1.32.12 - github.com/aws/aws-sdk-go-v2/credentials v1.19.12 - github.com/aws/aws-sdk-go-v2/service/ec2 v1.296.0 - github.com/aws/aws-sdk-go-v2/service/ecs v1.74.0 - github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.12 - github.com/aws/aws-sdk-go-v2/service/kafka v1.49.1 - github.com/aws/aws-sdk-go-v2/service/lightsail v1.51.0 - github.com/aws/aws-sdk-go-v2/service/rds v1.117.0 - github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 - github.com/aws/smithy-go v1.24.2 + github.com/aws/aws-sdk-go-v2 v1.41.7 + github.com/aws/aws-sdk-go-v2/config v1.32.17 + github.com/aws/aws-sdk-go-v2/credentials v1.19.16 + github.com/aws/aws-sdk-go-v2/service/ec2 v1.301.0 + github.com/aws/aws-sdk-go-v2/service/ecs v1.79.1 + github.com/aws/aws-sdk-go-v2/service/elasticache v1.52.2 + github.com/aws/aws-sdk-go-v2/service/kafka v1.51.0 + github.com/aws/aws-sdk-go-v2/service/lightsail v1.53.2 + github.com/aws/aws-sdk-go-v2/service/rds v1.118.2 + github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 + github.com/aws/smithy-go v1.25.1 github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 github.com/cespare/xxhash/v2 v2.3.0 github.com/dennwc/varint v1.0.0 - github.com/digitalocean/godo v1.178.0 + github.com/digitalocean/godo v1.189.0 github.com/edsrzf/mmap-go v1.2.1-0.20241212181136-fad1cd13edbd github.com/envoyproxy/go-control-plane/envoy v1.37.0 github.com/envoyproxy/protoc-gen-validate v1.3.3 github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb github.com/felixge/fgprof v0.9.5 - github.com/fsnotify/fsnotify v1.9.0 - github.com/go-openapi/strfmt v0.26.1 + github.com/fsnotify/fsnotify v1.10.1 + github.com/go-openapi/strfmt v0.26.2 github.com/go-zookeeper/zk v1.0.4 github.com/gogo/protobuf v1.3.2 github.com/golang/snappy v1.0.0 github.com/google/go-cmp v0.7.0 - github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc + github.com/google/pprof v0.0.0-20260507013755-92041b743c96 github.com/google/uuid v1.6.0 - github.com/gophercloud/gophercloud/v2 v2.11.1 + github.com/gophercloud/gophercloud/v2 v2.12.0 github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 github.com/hashicorp/consul/api v1.32.1 - github.com/hashicorp/nomad/api v0.0.0-20260324203407-b27b0c2e019a - github.com/hetznercloud/hcloud-go/v2 v2.36.0 - github.com/ionos-cloud/sdk-go/v6 v6.3.6 + github.com/hashicorp/nomad/api v0.0.0-20260508212055-068227ba803f + github.com/hetznercloud/hcloud-go/v2 v2.40.0 + github.com/ionos-cloud/sdk-go/v6 v6.3.7 github.com/json-iterator/go v1.1.12 - github.com/klauspost/compress v1.18.5 + github.com/klauspost/compress v1.18.6 github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b - github.com/linode/linodego v1.66.0 + github.com/linode/linodego v1.69.0 github.com/miekg/dns v1.1.72 - github.com/moby/moby/api v1.54.0 - github.com/moby/moby/client v0.3.0 + github.com/moby/moby/api v1.54.2 + github.com/moby/moby/client v0.4.1 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f github.com/nsf/jsondiff v0.0.0-20260207060731-8e8d90c4c0ac github.com/oklog/run v1.2.0 github.com/oklog/ulid/v2 v2.1.1 - github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.148.0 - github.com/outscale/osc-sdk-go/v2 v2.32.0 + github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.151.0 + github.com/outscale/osc-sdk-go/v2 v2.34.0 github.com/ovh/go-ovh v1.9.0 - github.com/pb33f/libopenapi v0.34.4 - github.com/pb33f/libopenapi-validator v0.13.3 - github.com/prometheus/alertmanager v0.31.1 + github.com/pb33f/libopenapi v0.36.3 + github.com/pb33f/libopenapi-validator v0.13.7 + github.com/prometheus/alertmanager v0.32.1 github.com/prometheus/client_golang v1.23.2 - github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856 + github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303 github.com/prometheus/client_model v0.6.2 github.com/prometheus/common v0.67.5 github.com/prometheus/common/assets v0.2.0 - github.com/prometheus/exporter-toolkit v0.15.1 + github.com/prometheus/exporter-toolkit v0.16.0 github.com/prometheus/sigv4 v0.4.1 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36 github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c - github.com/stackitcloud/stackit-sdk-go/core v0.23.0 + github.com/stackitcloud/stackit-sdk-go/core v0.26.0 github.com/stretchr/testify v1.11.1 - github.com/vultr/govultr/v3 v3.28.1 - go.opentelemetry.io/collector/component v1.54.0 - go.opentelemetry.io/collector/consumer v1.54.0 - go.opentelemetry.io/collector/pdata v1.54.0 - go.opentelemetry.io/collector/processor v1.54.0 - go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.67.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 - go.opentelemetry.io/otel v1.42.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 - go.opentelemetry.io/otel/metric v1.42.0 - go.opentelemetry.io/otel/sdk v1.42.0 - go.opentelemetry.io/otel/trace v1.42.0 + github.com/vultr/govultr/v3 v3.31.1 + go.opentelemetry.io/collector/component v1.57.0 + go.opentelemetry.io/collector/consumer v1.57.0 + go.opentelemetry.io/collector/pdata v1.57.0 + go.opentelemetry.io/collector/processor v1.57.0 + go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 + go.opentelemetry.io/otel v1.43.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 + go.opentelemetry.io/otel/metric v1.43.0 + go.opentelemetry.io/otel/sdk v1.43.0 + go.opentelemetry.io/otel/trace v1.43.0 go.uber.org/atomic v1.11.0 go.uber.org/automaxprocs v1.6.0 go.uber.org/goleak v1.3.0 @@ -96,11 +96,11 @@ require ( go.yaml.in/yaml/v4 v4.0.0-rc.4 golang.org/x/oauth2 v0.36.0 golang.org/x/sync v0.20.0 - golang.org/x/sys v0.42.0 - golang.org/x/text v0.35.0 - google.golang.org/api v0.272.0 - google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 - google.golang.org/grpc v1.79.3 + golang.org/x/sys v0.44.0 + golang.org/x/text v0.37.0 + google.golang.org/api v0.278.0 + google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348 + google.golang.org/grpc v1.81.0 google.golang.org/protobuf v1.36.11 k8s.io/api v0.35.3 k8s.io/apimachinery v0.35.3 @@ -111,14 +111,15 @@ require ( require ( github.com/aws/aws-sdk-go v1.55.8 // indirect - github.com/aws/aws-sdk-go-v2/service/signin v1.0.8 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/basgys/goxml2json v1.1.1-0.20231018121955-e66ee54ceaad // indirect github.com/buger/jsonparser v1.1.2 // indirect github.com/go-openapi/swag/cmdutils v0.25.5 // indirect github.com/go-openapi/swag/conv v0.25.5 // indirect github.com/go-openapi/swag/fileutils v0.25.5 // indirect - github.com/go-openapi/swag/jsonname v0.25.5 // indirect + github.com/go-openapi/swag/jsonname v0.26.0 // indirect github.com/go-openapi/swag/jsonutils v0.25.5 // indirect github.com/go-openapi/swag/loading v0.25.5 // indirect github.com/go-openapi/swag/mangling v0.25.5 // indirect @@ -130,40 +131,40 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pb33f/jsonpath v0.8.2 // indirect github.com/pb33f/ordered-map/v2 v2.3.1 // indirect - github.com/puzpuzpuz/xsync/v4 v4.4.0 // indirect + github.com/puzpuzpuz/xsync/v4 v4.5.0 // indirect github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect - go.opentelemetry.io/collector/internal/componentalias v0.148.0 // indirect + go.opentelemetry.io/collector/internal/componentalias v0.151.0 // indirect go.uber.org/multierr v1.11.0 // indirect + golang.org/x/tools/godoc v0.1.0-deprecated // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect ) require ( - cloud.google.com/go/auth v0.18.2 // indirect + cloud.google.com/go/auth v0.20.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.9.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/armon/go-metrics v0.4.1 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20 - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.30.13 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 - github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect + github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect - github.com/coreos/go-systemd/v22 v22.6.0 // indirect + github.com/coreos/go-systemd/v22 v22.7.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/go-connections v0.6.0 // indirect + github.com/docker/go-connections v0.7.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/fatih/color v1.18.0 // indirect @@ -171,9 +172,9 @@ require ( github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.24.3 // indirect + github.com/go-openapi/analysis v0.25.0 // indirect github.com/go-openapi/errors v0.22.7 // indirect - github.com/go-openapi/jsonpointer v0.22.5 // indirect + github.com/go-openapi/jsonpointer v0.23.1 // indirect github.com/go-openapi/jsonreference v0.21.5 // indirect github.com/go-openapi/loads v0.23.3 // indirect github.com/go-openapi/spec v0.22.4 // indirect @@ -186,10 +187,10 @@ require ( github.com/google/gnostic-models v0.7.0 // indirect github.com/google/go-querystring v1.2.0 // indirect github.com/google/s2a-go v0.1.9 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect - github.com/googleapis/gax-go/v2 v2.18.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.15 // indirect + github.com/googleapis/gax-go/v2 v2.22.0 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect github.com/hashicorp/cronexpr v1.1.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -198,14 +199,14 @@ require ( github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.8 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect - github.com/hashicorp/go-version v1.8.0 // indirect + github.com/hashicorp/go-version v1.9.0 // indirect github.com/hashicorp/golang-lru v0.6.0 // indirect github.com/hashicorp/serf v0.10.1 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/providers/confmap v1.0.0 // indirect - github.com/knadh/koanf/v2 v2.3.3 // indirect + github.com/knadh/koanf/v2 v2.3.4 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -217,8 +218,8 @@ require ( github.com/moby/docker-image-spec v1.3.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.148.0 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.148.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.151.0 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.151.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect @@ -232,23 +233,23 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/confmap v1.54.0 // indirect - go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 // indirect - go.opentelemetry.io/collector/featuregate v1.54.0 // indirect - go.opentelemetry.io/collector/pipeline v1.54.0 // indirect - go.opentelemetry.io/proto/otlp v1.9.0 // indirect - go.uber.org/zap v1.27.1 // indirect - golang.org/x/crypto v0.49.0 // indirect + go.opentelemetry.io/collector/confmap v1.57.0 // indirect + go.opentelemetry.io/collector/confmap/xconfmap v0.151.0 // indirect + go.opentelemetry.io/collector/featuregate v1.57.0 // indirect + go.opentelemetry.io/collector/pipeline v1.57.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect + go.uber.org/zap v1.28.0 // indirect + golang.org/x/crypto v0.50.0 // indirect golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect - golang.org/x/mod v0.33.0 // indirect - golang.org/x/net v0.52.0 // indirect - golang.org/x/term v0.41.0 // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/net v0.53.0 // indirect + golang.org/x/term v0.42.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.42.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c // indirect + golang.org/x/tools v0.44.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/ini.v1 v1.67.1 // indirect + gopkg.in/ini.v1 v1.67.2 // indirect k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect diff --git a/go.sum b/go.sum index b01c94a3cc..7375c36521 100644 --- a/go.sum +++ b/go.sum @@ -1,17 +1,17 @@ -cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= -cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= +cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA= +cloud.google.com/go/auth v0.20.0/go.mod h1:942/yi/itH1SsmpyrbnTMDgGfdy2BUqIKyd0cyYLc5Q= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 h1:fou+2+WFTib47nS+nz/ozhEBnvU96bKHy6LjRsY4E28= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0/go.mod h1:t76Ruy8AHvUAC8GfMWJMa0ElSbuIcO03NLpynfbgsPA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 h1:jHb/wfvRikGdxMXYV3QG/SzUOPYN9KEUUuC0Yd0/vC0= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1/go.mod h1:pzBXCYn05zvYIrwLgtK8Ap8QcjRg+0i76tMQdWN6wOk= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6XuRW0nU7hgg4zlmZZa+a9q4= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0 h1:LkHbJbgF3YyvC53aqYGR+wWQDn2Rdp9AQdGndf9QvY4= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5 v5.7.0/go.mod h1:QyiQdW4f4/BIfB8ZutZ2s+28RAgfa/pT+zS++ZHyM1I= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do= @@ -49,46 +49,46 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ= github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk= -github.com/aws/aws-sdk-go-v2 v1.41.4 h1:10f50G7WyU02T56ox1wWXq+zTX9I1zxG46HYuG1hH/k= -github.com/aws/aws-sdk-go-v2 v1.41.4/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= -github.com/aws/aws-sdk-go-v2/config v1.32.12 h1:O3csC7HUGn2895eNrLytOJQdoL2xyJy0iYXhoZ1OmP0= -github.com/aws/aws-sdk-go-v2/config v1.32.12/go.mod h1:96zTvoOFR4FURjI+/5wY1vc1ABceROO4lWgWJuxgy0g= -github.com/aws/aws-sdk-go-v2/credentials v1.19.12 h1:oqtA6v+y5fZg//tcTWahyN9PEn5eDU/Wpvc2+kJ4aY8= -github.com/aws/aws-sdk-go-v2/credentials v1.19.12/go.mod h1:U3R1RtSHx6NB0DvEQFGyf/0sbrpJrluENHdPy1j/3TE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20 h1:zOgq3uezl5nznfoK3ODuqbhVg1JzAGDUhXOsU0IDCAo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20/go.mod h1:z/MVwUARehy6GAg/yQ1GO2IMl0k++cu1ohP9zo887wE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 h1:CNXO7mvgThFGqOFgbNAP2nol2qAWBOGfqR/7tQlvLmc= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20/go.mod h1:oydPDJKcfMhgfcgBUZaG+toBbwy8yPWubJXBVERtI4o= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 h1:tN6W/hg+pkM+tf9XDkWUbDEjGLb+raoBMFsTodcoYKw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20/go.mod h1:YJ898MhD067hSHA6xYCx5ts/jEd8BSOLtQDL3iZsvbc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.296.0 h1:98Miqj16un1WLNyM1RjVDhXYumhqZrQfAeG8i4jPG6o= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.296.0/go.mod h1:T6ndRfdhnXLIY5oKBHjYZDVj706los2zGdpThppquvA= -github.com/aws/aws-sdk-go-v2/service/ecs v1.74.0 h1:YS5TXaEvzDb+sV+wdQFUtuCAk0GeFR9Ai6HFdxpz6q8= -github.com/aws/aws-sdk-go-v2/service/ecs v1.74.0/go.mod h1:10kBgdaNJz0FO/+JWDUH+0rtSjkn5yafgavDDmmhFzs= -github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.12 h1:S066ajzfPRCSW4lsSHOYglne6SNi2CHt1u5omzW1RBg= -github.com/aws/aws-sdk-go-v2/service/elasticache v1.51.12/go.mod h1:86SE4NcXxbxr8KTG3yOyDmd4HyiFmKl8TexXnhYJ+Bw= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 h1:2HvVAIq+YqgGotK6EkMf+KIEqTISmTYh5zLpYyeTo1Y= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20/go.mod h1:V4X406Y666khGa8ghKmphma/7C0DAtEQYhkq9z4vpbk= -github.com/aws/aws-sdk-go-v2/service/kafka v1.49.1 h1:BgBatWcQIFqF1l6KGHjv66V0d/ISnWrTwxDx/Jf6EJM= -github.com/aws/aws-sdk-go-v2/service/kafka v1.49.1/go.mod h1:pMpys+PlrN//vj8j5s0oOAMJjauj81VkHzIZxPVWOro= -github.com/aws/aws-sdk-go-v2/service/lightsail v1.51.0 h1:cg6PxzoIide2wiEyLfikOFN+XwHafwR8p5+L9U1E8dQ= -github.com/aws/aws-sdk-go-v2/service/lightsail v1.51.0/go.mod h1:YvX7hjUWecrKX8fBkbEncyddEW85xjNH+u5JHioITOw= -github.com/aws/aws-sdk-go-v2/service/rds v1.117.0 h1:T1Xe9sYxSUUQOvd1RsFeVk/IXFPdqSiN0atXu/Hy/8A= -github.com/aws/aws-sdk-go-v2/service/rds v1.117.0/go.mod h1:QbXW4coAMakHQhf1qhE0eVVCen9gwB/Kvn+HHHKhpGY= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.8 h1:0GFOLzEbOyZABS3PhYfBIx2rNBACYcKty+XGkTgw1ow= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.8/go.mod h1:LXypKvk85AROkKhOG6/YEcHFPoX+prKTowKnVdcaIxE= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.13 h1:kiIDLZ005EcKomYYITtfsjn7dtOwHDOFy7IbPXKek2o= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.13/go.mod h1:2h/xGEowcW/g38g06g3KpRWDlT+OTfxxI0o1KqayAB8= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 h1:jzKAXIlhZhJbnYwHbvUQZEB8KfgAEuG0dc08Bkda7NU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17/go.mod h1:Al9fFsXjv4KfbzQHGe6V4NZSZQXecFcvaIF4e70FoRA= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 h1:Cng+OOwCHmFljXIxpEVXAGMnBia8MSU6Ch5i9PgBkcU= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.9/go.mod h1:LrlIndBDdjA/EeXeyNBle+gyCwTlizzW5ycgWnvIxkk= -github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= -github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/aws/aws-sdk-go-v2 v1.41.7 h1:DWpAJt66FmnnaRIOT/8ASTucrvuDPZASqhhLey6tLY8= +github.com/aws/aws-sdk-go-v2 v1.41.7/go.mod h1:4LAfZOPHNVNQEckOACQx60Y8pSRjIkNZQz1w92xpMJc= +github.com/aws/aws-sdk-go-v2/config v1.32.17 h1:FpL4/758/diKwqbytU0prpuiu60fgXKUWCpDJtApclU= +github.com/aws/aws-sdk-go-v2/config v1.32.17/go.mod h1:OXqUMzgXytfoF9JaKkhrOYsyh72t9G+MJH8mMRaexOE= +github.com/aws/aws-sdk-go-v2/credentials v1.19.16 h1:r3RJBuU7X9ibt8RHbMjWE6y60QbKBiII6wSrXnapxSU= +github.com/aws/aws-sdk-go-v2/credentials v1.19.16/go.mod h1:6cx7zqDENJDbBIIWX6P8s0h6hqHC8Avbjh9Dseo27ug= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 h1:UuSfcORqNSz/ey3VPRS8TcVH2Ikf0/sC+Hdj400QI6U= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23/go.mod h1:+G/OSGiOFnSOkYloKj/9M35s74LgVAdJBSD5lsFfqKg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 h1:GpT/TrnBYuE5gan2cZbTtvP+JlHsutdmlV2YfEyNde0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23/go.mod h1:xYWD6BS9ywC5bS3sz9Xh04whO/hzK2plt2Zkyrp4JuA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 h1:bpd8vxhlQi2r1hiueOw02f/duEPTMK59Q4QMAoTTtTo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23/go.mod h1:15DfR2nw+CRHIk0tqNyifu3G1YdAOy68RftkhMDDwYk= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 h1:OQqn11BtaYv1WLUowvcA30MpzIu8Ti4pcLPIIyoKZrA= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24/go.mod h1:X5ZJyfwVrWA96GzPmUCWFQaEARPR7gCrpq2E92PJwAE= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.301.0 h1:U+cZAMc8mN0jne8/ae7KrrFuILTXrZReAvc6BIpXGls= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.301.0/go.mod h1:Y95W0Hm6FYLPa6o0hbnJ+sWgmdc4ifcLFjGkdobWVhY= +github.com/aws/aws-sdk-go-v2/service/ecs v1.79.1 h1:tQNU4tC4cMoZo1e+7J8j3/GWM7PJFdXCN0VzEFwFqUE= +github.com/aws/aws-sdk-go-v2/service/ecs v1.79.1/go.mod h1:TIKZ9zIFS6W2k9FeW+r5sGVnlxp+aUt9oQ/St3Suj1o= +github.com/aws/aws-sdk-go-v2/service/elasticache v1.52.2 h1:5wbCUfyxXcjIqesyVfJBBJs0bDMyejthtHyy48mfZCI= +github.com/aws/aws-sdk-go-v2/service/elasticache v1.52.2/go.mod h1:o4vQxDt6oteknUjkXIEskp0ccy+93NRTPKXw3HlVMFE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 h1:FLudkZLt5ci0ozzgkVo8BJGwvqNaZbTWb3UcucAateA= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9/go.mod h1:w7wZ/s9qK7c8g4al+UyoF1Sp/Z45UwMGcqIzLWVQHWk= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 h1:pbrxO/kuIwgEsOPLkaHu0O+m4fNgLU8B3vxQ+72jTPw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23/go.mod h1:/CMNUqoj46HpS3MNRDEDIwcgEnrtZlKRaHNaHxIFpNA= +github.com/aws/aws-sdk-go-v2/service/kafka v1.51.0 h1:ovcPO5rh87iOWFMLAwtgyHEzZOCx0WYemd7thWdnXME= +github.com/aws/aws-sdk-go-v2/service/kafka v1.51.0/go.mod h1:pW4pYNuVeScl13yqwsjLY0F/7g2YD8E0AvR6SOQsJZE= +github.com/aws/aws-sdk-go-v2/service/lightsail v1.53.2 h1:frwYj+OqTr28EO/GFxuE9fsjOF/7WIOrklzusnV4Kzw= +github.com/aws/aws-sdk-go-v2/service/lightsail v1.53.2/go.mod h1:Etcg8xorq1b0g0V2KMNgFjubYITZseJv08qtX/3szko= +github.com/aws/aws-sdk-go-v2/service/rds v1.118.2 h1:pkEeQneYFpTAnGhyqSbyp/DlCPPJTGt0GkWahlLYzMA= +github.com/aws/aws-sdk-go-v2/service/rds v1.118.2/go.mod h1:7gS+cGrKF0mH253QHFlStmx79ws+DlNk+04ZRfmw3U0= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 h1:TdJ+HdzOBhU8+iVAOGUTU63VXopcumCOF1paFulHWZc= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.11/go.mod h1:R82ZRExE/nheo0N+T8zHPcLRTcH8MGsnR3BiVGX0TwI= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 h1:7byT8HUWrgoRp6sXjxtZwgOKfhss5fW6SkLBtqzgRoE= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.17/go.mod h1:xNWknVi4Ezm1vg1QsB/5EWpAJURq22uqd38U8qKvOJc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21 h1:+1Kl1zx6bWi4X7cKi3VYh29h8BvsCoHQEQ6ST9X8w7w= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21/go.mod h1:4vIRDq+CJB2xFAXZ+YgGUTiEft7oAQlhIs71xcSeuVg= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 h1:F/M5Y9I3nwr2IEpshZgh1GeHpOItExNM9L1euNuh/fk= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.1/go.mod h1:mTNxImtovCOEEuD65mKW7DCsL+2gjEH+RPEAexAzAio= +github.com/aws/smithy-go v1.25.1 h1:J8ERsGSU7d+aCmdQur5Txg6bVoYelvQJgtZehD12GkI= +github.com/aws/smithy-go v1.25.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/basgys/goxml2json v1.1.1-0.20231018121955-e66ee54ceaad h1:3swAvbzgfaI6nKuDDU7BiKfZRdF+h2ZwKgMHd8Ha4t8= @@ -117,28 +117,28 @@ github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObk github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w= -github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik= +github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= -github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo= -github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU= +github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj9KI28KA= +github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE= github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= -github.com/digitalocean/godo v1.178.0 h1:+B4xGOaoFwwwpM7TKhoyGHdmFg5eF9zDB1YfOLvNJ2E= -github.com/digitalocean/godo v1.178.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU= +github.com/digitalocean/godo v1.189.0 h1:93hHWsZdbJdkMsfZ21lMkOmd+BPMCTzu/+FIJ5FvAL4= +github.com/digitalocean/godo v1.189.0/go.mod h1:xQsWpVCCbkDrWisHA72hPzPlnC+4W5w/McZY5ij9uvU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= -github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= -github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= -github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= +github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8= +github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c= +github.com/docker/go-connections v0.7.0/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/edsrzf/mmap-go v1.2.1-0.20241212181136-fad1cd13edbd h1:I4PrRZuNMeDP3VbFrak4QsqwO5tWkQf0tqrrr1L2DsU= @@ -160,8 +160,8 @@ github.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY= github.com/felixge/fgprof v0.9.5/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= +github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo= github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -174,20 +174,20 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/analysis v0.24.3 h1:a1hrvMr8X0Xt69KP5uVTu5jH62DscmDifrLzNglAayk= -github.com/go-openapi/analysis v0.24.3/go.mod h1:Nc+dWJ/FxZbhSow5Yh3ozg5CLJioB+XXT6MdLvJUsUw= +github.com/go-openapi/analysis v0.25.0 h1:EnjAq1yO8wEO9HbPmY8vLPEIkdZuuFhCAKBPvCB7bCs= +github.com/go-openapi/analysis v0.25.0/go.mod h1:5WFTRE43WLkPG9r9OtlMfqkkvUTYLVVCIxLlEpyF8kE= github.com/go-openapi/errors v0.22.7 h1:JLFBGC0Apwdzw3484MmBqspjPbwa2SHvpDm0u5aGhUA= github.com/go-openapi/errors v0.22.7/go.mod h1://QW6SD9OsWtH6gHllUCddOXDL0tk0ZGNYHwsw4sW3w= -github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= -github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0= +github.com/go-openapi/jsonpointer v0.23.1 h1:1HBACs7XIwR2RcmItfdSFlALhGbe6S92p0ry4d1GWg4= +github.com/go-openapi/jsonpointer v0.23.1/go.mod h1:iWRmZTrGn7XwYhtPt/fvdSFj1OfNBngqRT2UG3BxSqY= github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= github.com/go-openapi/loads v0.23.3 h1:g5Xap1JfwKkUnZdn+S0L3SzBDpcTIYzZ5Qaag0YDkKQ= github.com/go-openapi/loads v0.23.3/go.mod h1:NOH07zLajXo8y55hom0omlHWDVVvCwBM/S+csCK8LqA= github.com/go-openapi/spec v0.22.4 h1:4pxGjipMKu0FzFiu/DPwN3CTBRlVM2yLf/YTWorYfDQ= github.com/go-openapi/spec v0.22.4/go.mod h1:WQ6Ai0VPWMZgMT4XySjlRIE6GP1bGQOtEThn3gcWLtQ= -github.com/go-openapi/strfmt v0.26.1 h1:7zGCHji7zSYDC2tCXIusoxYQz/48jAf2q+sF6wXTG+c= -github.com/go-openapi/strfmt v0.26.1/go.mod h1:Zslk5VZPOISLwmWTMBIS7oiVFem1o1EI6zULY8Uer7Y= +github.com/go-openapi/strfmt v0.26.2 h1:ysjheCh4i1rmFEo2LanhELDNucNzfWTZhUDKgWWPaFM= +github.com/go-openapi/strfmt v0.26.2/go.mod h1:fXh1e449cyUn2NYuz+wb3wARBUdMl7qPEZwX00nqivY= github.com/go-openapi/swag v0.25.5 h1:pNkwbUEeGwMtcgxDr+2GBPAk4kT+kJ+AaB+TMKAg+TU= github.com/go-openapi/swag v0.25.5/go.mod h1:B3RT6l8q7X803JRxa2e59tHOiZlX1t8viplOcs9CwTA= github.com/go-openapi/swag/cmdutils v0.25.5 h1:yh5hHrpgsw4NwM9KAEtaDTXILYzdXh/I8Whhx9hKj7c= @@ -196,8 +196,8 @@ github.com/go-openapi/swag/conv v0.25.5 h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+ github.com/go-openapi/swag/conv v0.25.5/go.mod h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k= github.com/go-openapi/swag/fileutils v0.25.5 h1:B6JTdOcs2c0dBIs9HnkyTW+5gC+8NIhVBUwERkFhMWk= github.com/go-openapi/swag/fileutils v0.25.5/go.mod h1:V3cT9UdMQIaH4WiTrUc9EPtVA4txS0TOmRURmhGF4kc= -github.com/go-openapi/swag/jsonname v0.25.5 h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo= -github.com/go-openapi/swag/jsonname v0.25.5/go.mod h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU= +github.com/go-openapi/swag/jsonname v0.26.0 h1:gV1NFX9M8avo0YSpmWogqfQISigCmpaiNci8cGECU5w= +github.com/go-openapi/swag/jsonname v0.26.0/go.mod h1:urBBR8bZNoDYGr653ynhIx+gTeIz0ARZxHkAPktJK2M= github.com/go-openapi/swag/jsonutils v0.25.5 h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo= github.com/go-openapi/swag/jsonutils v0.25.5/go.mod h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4= github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5 h1:SX6sE4FrGb4sEnnxbFL/25yZBb5Hcg1inLeErd86Y1U= @@ -216,8 +216,8 @@ github.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT github.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ= github.com/go-openapi/testify/enable/yaml/v2 v2.4.1 h1:NZOrZmIb6PTv5LTFxr5/mKV/FjbUzGE7E6gLz7vFoOQ= github.com/go-openapi/testify/enable/yaml/v2 v2.4.1/go.mod h1:r7dwsujEHawapMsxA69i+XMGZrQ5tRauhLAjV/sxg3Q= -github.com/go-openapi/testify/v2 v2.4.1 h1:zB34HDKj4tHwyUQHrUkpV0Q0iXQ6dUCOQtIqn8hE6Iw= -github.com/go-openapi/testify/v2 v2.4.1/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-openapi/testify/v2 v2.4.2 h1:tiByHpvE9uHrrKjOszax7ZvKB7QOgizBWGBLuq0ePx4= +github.com/go-openapi/testify/v2 v2.4.2/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= github.com/go-openapi/validate v0.25.2 h1:12NsfLAwGegqbGWr2CnvT65X/Q2USJipmJ9b7xDJZz0= github.com/go-openapi/validate v0.25.2/go.mod h1:Pgl1LpPPGFnZ+ys4/hTlDiRYQdI1ocKypgE+8Q8BLfY= github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk= @@ -260,24 +260,24 @@ github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfh github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc h1:VBbFa1lDYWEeV5FZKUiYKYT0VxCp9twUmmaq9eb8sXw= -github.com/google/pprof v0.0.0-20260302011040-a15ffb7f9dcc/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= +github.com/google/pprof v0.0.0-20260507013755-92041b743c96 h1:YDDnaZ9afWajDboPMt9Vikqca/yWAX7KAxVzb4lJU1M= +github.com/google/pprof v0.0.0-20260507013755-92041b743c96/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI= github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8= -github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= -github.com/googleapis/gax-go/v2 v2.18.0 h1:jxP5Uuo3bxm3M6gGtV94P4lliVetoCB4Wk2x8QA86LI= -github.com/googleapis/gax-go/v2 v2.18.0/go.mod h1:uSzZN4a356eRG985CzJ3WfbFSpqkLTjsnhWGJR6EwrE= -github.com/gophercloud/gophercloud/v2 v2.11.1 h1:jCs4vLH8sJgRqrPzqVfWgl7uI6JnIIlsgeIRM0uHjxY= -github.com/gophercloud/gophercloud/v2 v2.11.1/go.mod h1:Rm0YvKQ4QYX2rY9XaDKnjRzSGwlG5ge4h6ABYnmkKQM= +github.com/googleapis/enterprise-certificate-proxy v0.3.15 h1:xolVQTEXusUcAA5UgtyRLjelpFFHWlPQ4XfWGc7MBas= +github.com/googleapis/enterprise-certificate-proxy v0.3.15/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= +github.com/googleapis/gax-go/v2 v2.22.0 h1:PjIWBpgGIVKGoCXuiCoP64altEJCj3/Ei+kSU5vlZD4= +github.com/googleapis/gax-go/v2 v2.22.0/go.mod h1:irWBbALSr0Sk3qlqb9SyJ1h68WjgeFuiOzI4Rqw5+aY= +github.com/gophercloud/gophercloud/v2 v2.12.0 h1:Gxmc/Bog1UDKkxTcQW7MSPTDviJXpLeEgVeN5KrxoCo= +github.com/gophercloud/gophercloud/v2 v2.12.0/go.mod h1:H7TTOxbLy8RIaHSNhI2GCrWIzw4Xpw8Xn2mBhCUT5kA= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 h1:cLN4IBkmkYZNnk7EAJ0BHIethd+J6LqxFNw5mSiI2bM= github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= github.com/hashicorp/consul/api v1.32.1 h1:0+osr/3t/aZNAdJX558crU3PEjVrG4x6715aZHRgceE= github.com/hashicorp/consul/api v1.32.1/go.mod h1:mXUWLnxftwTmDv4W3lzxYCPD199iNLLUyLfLGFJbtl4= github.com/hashicorp/consul/sdk v0.16.1 h1:V8TxTnImoPD5cj0U9Spl0TUxcytjcbbJeADFF07KdHg= @@ -319,8 +319,8 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= -github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA= +github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.6.0 h1:uL2shRDx7RTrOrTCUZEGP/wJUFiUI8QT6E7z5o8jga4= github.com/hashicorp/golang-lru v0.6.0/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -329,15 +329,15 @@ github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/ github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/memberlist v0.5.4 h1:40YY+3qq2tAUhZIMEK8kqusKZBBjdwJ3NUjvYkcxh74= github.com/hashicorp/memberlist v0.5.4/go.mod h1:OgN6xiIo6RlHUWk+ALjP9e32xWCoQrsOCmHrWCm2MWA= -github.com/hashicorp/nomad/api v0.0.0-20260324203407-b27b0c2e019a h1:HGwfgBNl90YBiHdbzZ/+8aMxO1UL9B/yNTAXa8iB8z8= -github.com/hashicorp/nomad/api v0.0.0-20260324203407-b27b0c2e019a/go.mod h1:KkLNLU0Nyfh5jWsFoF/PsmMbKpRIAoIV4lmQoJWgKCk= +github.com/hashicorp/nomad/api v0.0.0-20260508212055-068227ba803f h1:T3PgfZZqrpDWAKQGk1SDC23LgK+ac42u66WrzymA8Zg= +github.com/hashicorp/nomad/api v0.0.0-20260508212055-068227ba803f/go.mod h1:KkLNLU0Nyfh5jWsFoF/PsmMbKpRIAoIV4lmQoJWgKCk= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hetznercloud/hcloud-go/v2 v2.36.0 h1:HlLL/aaVXUulqe+rsjoJmrxKhPi1MflL5O9iq5QEtvo= -github.com/hetznercloud/hcloud-go/v2 v2.36.0/go.mod h1:MnN/QJEa/RYNQiiVoJjNHPntM7Z1wlYPgJ2HA40/cDE= +github.com/hetznercloud/hcloud-go/v2 v2.40.0 h1:fuP7khfiDQAIXdKyQq7f3LnnOjyZg0PXTafXjUKkqIA= +github.com/hetznercloud/hcloud-go/v2 v2.40.0/go.mod h1:ANz38eerXjPv00dm9dckKhttOGtYeeGmjjvwL5e6c5E= github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= -github.com/ionos-cloud/sdk-go/v6 v6.3.6 h1:l/TtKgdQ1wUH3DDe2SfFD78AW+TJWdEbDpQhHkWd6CM= -github.com/ionos-cloud/sdk-go/v6 v6.3.6/go.mod h1:nUGHP4kZHAZngCVr4v6C8nuargFrtvt7GrzH/hqn7c4= +github.com/ionos-cloud/sdk-go/v6 v6.3.7 h1:t773JkC/asnyVqeQ+OvN9WCRZuosSoPtJfyM82EFCWY= +github.com/ionos-cloud/sdk-go/v6 v6.3.7/go.mod h1:nUGHP4kZHAZngCVr4v6C8nuargFrtvt7GrzH/hqn7c4= github.com/jarcoal/httpmock v1.4.1 h1:0Ju+VCFuARfFlhVXFc2HxlcQkfB+Xq12/EotHko+x2A= github.com/jarcoal/httpmock v1.4.1/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -358,14 +358,14 @@ github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRt github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= -github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= +github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= github.com/knadh/koanf/maps v0.1.2/go.mod h1:npD/QZY3V6ghQDdcQzl1W4ICNVTkohC8E73eI2xW4yI= github.com/knadh/koanf/providers/confmap v1.0.0 h1:mHKLJTE7iXEys6deO5p6olAiZdG5zwp8Aebir+/EaRE= github.com/knadh/koanf/providers/confmap v1.0.0/go.mod h1:txHYHiI2hAtF0/0sCmcuol4IDcuQbKTybiB1nOcUo1A= -github.com/knadh/koanf/v2 v2.3.3 h1:jLJC8XCRfLC7n4F+ZKKdBsbq1bfXTpuFhf4L7t94D94= -github.com/knadh/koanf/v2 v2.3.3/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= +github.com/knadh/koanf/v2 v2.3.4 h1:fnynNSDlujWE+v83hAp8wKr/cdoxHLO0629SN+U8Urc= +github.com/knadh/koanf/v2 v2.3.4/go.mod h1:gRb40VRAbd4iJMYYD5IxZ6hfuopFcXBpc9bbQpZwo28= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -380,8 +380,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= -github.com/linode/linodego v1.66.0 h1:rK8QJFaV53LWOEJvb/evhTg/dP5ElvtuZmx4iv4RJds= -github.com/linode/linodego v1.66.0/go.mod h1:12ykGs9qsvxE+OU3SXuW2w+DTruWF35FPlXC7gGk2tU= +github.com/linode/linodego v1.69.0 h1:5Qsv6kwoTwwOBETfgietEg5UcaKg1bQEN0DDYc2wIeM= +github.com/linode/linodego v1.69.0/go.mod h1:QPzvRKCy9oz1lRaIACPRORoAI9AAfKKg2AR5mXujoB0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -420,10 +420,10 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/moby/api v1.54.0 h1:7kbUgyiKcoBhm0UrWbdrMs7RX8dnwzURKVbZGy2GnL0= -github.com/moby/moby/api v1.54.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= -github.com/moby/moby/client v0.3.0 h1:UUGL5okry+Aomj3WhGt9Aigl3ZOxZGqR7XPo+RLPlKs= -github.com/moby/moby/client v0.3.0/go.mod h1:HJgFbJRvogDQjbM8fqc1MCEm4mIAGMLjXbgwoZp6jCQ= +github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg= +github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= +github.com/moby/moby/client v0.4.1 h1:DMQgisVoMkmMs7fp3ROSdiBnoAu8+vo3GggFl06M/wY= +github.com/moby/moby/client v0.4.1/go.mod h1:z52C9O2POPOsnxZAy//WtKcQ32P+jT/NGeXu/7nfjGQ= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -447,19 +447,19 @@ github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.148.0 h1:CiTjQE/Hh5xK2t56ogrDK4nl0+tJPNmASCs4zEYZ/xU= -github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.148.0/go.mod h1:WUFkzTiOpt7EYyL67gv1GOf3RD8qKWGtin3lY9LYzW4= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.148.0 h1:1TLg6YrS3Au6F7xw3ws2Njbwj13IMqPplvGFi+18fWs= -github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.148.0/go.mod h1:P8hZEDIQk4REgUWyLhSVRHwTxK6KkifKfg36BmmQ/DI= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.148.0 h1:xgD/kNGp/wWY+bwY599Pc01OamYN17phRiTP934bM5Y= -github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.148.0/go.mod h1:ZK7wvaefla9lB3bAW0rNKt7IzRPcTRQoOFqr4sZy/XM= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.151.0 h1:RAnPnD3DcYVzd+BbPGtauEsy86BCjSa+SEykD6y3oKo= +github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.151.0/go.mod h1:B2rs2x914jqvMApxRWs8R/fjtnJFy6Ml8bnaZHChKVQ= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.151.0 h1:c8+upXGwDxokINkuChSD7INYHlpcCAyQs2aXpx4rzSs= +github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.151.0/go.mod h1:Ln3K9yJgPAwEUXqCoR8htVs6bk3cyj6zIPOyM/LhiPo= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.151.0 h1:ba6grxqvfpW4++JoP/dlOk6oV2g88DJ2wBQ+yTVyshQ= +github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.151.0/go.mod h1:oUwKfAyARk9N1m+ZndqDepHIGyFBTubitsnVqWKcLNs= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= -github.com/outscale/osc-sdk-go/v2 v2.32.0 h1:twcX7/YF32aowN0khwK3fPKXGujRi7oOCLLzWcLTX+M= -github.com/outscale/osc-sdk-go/v2 v2.32.0/go.mod h1:fl+1NvnHptNVE0N57dkDa+H4fyBhlrFaRA+lYiUT44s= +github.com/outscale/osc-sdk-go/v2 v2.34.0 h1:hHH5W9Fmgt6b8nGUmDyu4vVP+zqJ+W0zflzjgsGEGUQ= +github.com/outscale/osc-sdk-go/v2 v2.34.0/go.mod h1:6J8WRznaSIEXXVHhhTXisGJQgvE5fYzbf8hAw7YIGfQ= github.com/ovh/go-ovh v1.9.0 h1:6K8VoL3BYjVV3In9tPJUdT7qMx9h0GExN9EXx1r2kKE= github.com/ovh/go-ovh v1.9.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -467,10 +467,10 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pb33f/jsonpath v0.8.2 h1:Ou4C7zjYClBm97dfZjDCjdZGusJoynv/vrtiEKNfj2Y= github.com/pb33f/jsonpath v0.8.2/go.mod h1:zBV5LJW4OQOPatmQE2QdKpGQJvhDTlE5IEj6ASaRNTo= -github.com/pb33f/libopenapi v0.34.4 h1:BWWXA3U4SlsHEvfczk+DJHu2O38ktgKw+zBEYaDZ2uI= -github.com/pb33f/libopenapi v0.34.4/go.mod h1:MsDdUlQ1CdrIDO5v26JfgBxQs7kcaOUEpMP3EqU6bI4= -github.com/pb33f/libopenapi-validator v0.13.3 h1:5KW4Y/mMoQvt6d89rLiNmW1zSfln7Oua2A0BqPXpjro= -github.com/pb33f/libopenapi-validator v0.13.3/go.mod h1:X58CRsmj/7l0iXethEMfq3OJIzQ5hces7EbJ071z6WI= +github.com/pb33f/libopenapi v0.36.3 h1:mScoyT/2ZY2NButTd1KQjtP5BVLv20pPaLti7uhCBw8= +github.com/pb33f/libopenapi v0.36.3/go.mod h1:MsDdUlQ1CdrIDO5v26JfgBxQs7kcaOUEpMP3EqU6bI4= +github.com/pb33f/libopenapi-validator v0.13.7 h1:9rMZjvoG9Qp9u2pr//EKl0cM+Qiwve5pY3Os0qoRC0M= +github.com/pb33f/libopenapi-validator v0.13.7/go.mod h1:zkbQL07GQANm5UNSvm7Lk5ofDL9GnD4TyCnzHus5lZI= github.com/pb33f/ordered-map/v2 v2.3.1 h1:5319HDO0aw4DA4gzi+zv4FXU9UlSs3xGZ40wcP1nBjY= github.com/pb33f/ordered-map/v2 v2.3.1/go.mod h1:qxFQgd0PkVUtOMCkTapqotNgzRhMPL7VvaHKbd1HnmQ= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= @@ -491,15 +491,15 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/alertmanager v0.31.1 h1:eAmIC42lzbWslHkMt693T36qdxfyZULswiHr681YS3Q= -github.com/prometheus/alertmanager v0.31.1/go.mod h1:zWPQwhbLt2ybee8rL921UONeQ59Oncash+m/hGP17tU= +github.com/prometheus/alertmanager v0.32.1 h1:BQ3jHXNq2A7VSD9Kh0Qx+kXbifNbHSDuKVbMmdRHHJ0= +github.com/prometheus/alertmanager v0.32.1/go.mod h1:0Dy9faTtMgpVYxJVxV0o65elTxHnSRCF/7gy5BKGZiE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= -github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856 h1:1Y6bmpZb8peQCy1IpctnAhIFuyhrdtMaDnETChhSNns= -github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856/go.mod h1:Vf0QcmVhGqpjLxZOaWrFSep86vchQtJmbztFaMM4f6Q= +github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303 h1:PCg3CbvxfRdQOzkVLL6rdWJS2IkobPyAk7nouqiuA9c= +github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303/go.mod h1:vW/EVguzbNw6xMRmozJQWbY60/+Zsg0TgVJOSXGx2iI= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -511,8 +511,8 @@ github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTU github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= github.com/prometheus/common/assets v0.2.0 h1:0P5OrzoHrYBOSM1OigWL3mY8ZvV2N4zIE/5AahrSrfM= github.com/prometheus/common/assets v0.2.0/go.mod h1:D17UVUE12bHbim7HzwUvtqm6gwBEaDQ0F+hIGbFbccI= -github.com/prometheus/exporter-toolkit v0.15.1 h1:XrGGr/qWl8Gd+pqJqTkNLww9eG8vR/CoRk0FubOKfLE= -github.com/prometheus/exporter-toolkit v0.15.1/go.mod h1:P/NR9qFRGbCFgpklyhix9F6v6fFr/VQB/CVsrMDGKo4= +github.com/prometheus/exporter-toolkit v0.16.0 h1:xT/j7L2XKF+VJd6B4fpUw6xWabHrSmsUf6mYmFqyu0s= +github.com/prometheus/exporter-toolkit v0.16.0/go.mod h1:d1EL8Z9674xQe/iWhwP2wDyCEoBPbXVeqDbqAUsgJWY= github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos= github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -522,8 +522,8 @@ github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzM github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/prometheus/sigv4 v0.4.1 h1:EIc3j+8NBea9u1iV6O5ZAN8uvPq2xOIUPcqCTivHuXs= github.com/prometheus/sigv4 v0.4.1/go.mod h1:eu+ZbRvsc5TPiHwqh77OWuCnWK73IdkETYY46P4dXOU= -github.com/puzpuzpuz/xsync/v4 v4.4.0 h1:vlSN6/CkEY0pY8KaB0yqo/pCLZvp9nhdbBdjipT4gWo= -github.com/puzpuzpuz/xsync/v4 v4.4.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo= +github.com/puzpuzpuz/xsync/v4 v4.5.0 h1:vOSWu6b57/emh+L/Cw0BeQfvxa/cogFywXHeGUxQxAg= +github.com/puzpuzpuz/xsync/v4 v4.5.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= @@ -541,8 +541,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stackitcloud/stackit-sdk-go/core v0.23.0 h1:zPrOhf3Xe47rKRs1fg/AqKYUiJJRYjdcv+3qsS50mEs= -github.com/stackitcloud/stackit-sdk-go/core v0.23.0/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI= +github.com/stackitcloud/stackit-sdk-go/core v0.26.0 h1:jQEb9gkehfp6VCP6TcYk7BI10cz4l0KM2L6hqYBH2QA= +github.com/stackitcloud/stackit-sdk-go/core v0.26.0/go.mod h1:WU1hhxnjXw2EV7CYa1nlEvNpMiRY6CvmIOaHuL3pOaA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -561,8 +561,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8 github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/vultr/govultr/v3 v3.28.1 h1:KR3LhppYARlBujY7+dcrE7YKL0Yo9qXL+msxykKQrLI= -github.com/vultr/govultr/v3 v3.28.1/go.mod h1:2zyUw9yADQaGwKnwDesmIOlBNLrm7edsCfWHFJpWKf8= +github.com/vultr/govultr/v3 v3.31.1 h1:AoJRZ0WDS1J1otp2wk3OD4aYh4EQxFU+kvyOPdCe4+Y= +github.com/vultr/govultr/v3 v3.31.1/go.mod h1:2zyUw9yADQaGwKnwDesmIOlBNLrm7edsCfWHFJpWKf8= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= @@ -572,64 +572,64 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/collector/component v1.54.0 h1:LvtX0Tzz18n44OrUFVk77N1FNsejfWJqztB28hrmDM8= -go.opentelemetry.io/collector/component v1.54.0/go.mod h1:yUMBYsySY/sDcXm8kOzEoZxt+JLdala6hxzSW0npOxY= -go.opentelemetry.io/collector/component/componentstatus v0.148.0 h1:sCGRaXNQolHFhPjrNJEwQ1WZOf96iL99tzm9GxuZsvg= -go.opentelemetry.io/collector/component/componentstatus v0.148.0/go.mod h1:yqg3SpGQc22W3wGICdnb+2kZVW9daBr3+LrGUCHkKfc= -go.opentelemetry.io/collector/component/componenttest v0.148.0 h1:tBXJWmy2X6KD8S0QU2YZa2zYBqP+IycSM4iOtwDD2pA= -go.opentelemetry.io/collector/component/componenttest v0.148.0/go.mod h1:1c1+6mZOmI0raoya5vA/X0F+fawEjNS6tCEs5xLATtA= -go.opentelemetry.io/collector/confmap v1.54.0 h1:RUoxQ4uAYHTI57GfHh61D00tTQsXm9T88ozrAiicByc= -go.opentelemetry.io/collector/confmap v1.54.0/go.mod h1:mQxG8bk0IWIt9gbWMvzE+cRkOuCuzbzkNGBq2YJ4wNM= -go.opentelemetry.io/collector/confmap/xconfmap v0.148.0 h1:UW8MX5VlKJf67x4Et7J9kPwP9Rv4VSmJ+UUpgRcb//c= -go.opentelemetry.io/collector/confmap/xconfmap v0.148.0/go.mod h1:4qTMr3V0uSXXac9wVs/UD5fIqRKw5yIl58+Vjsc6RHM= -go.opentelemetry.io/collector/consumer v1.54.0 h1:RGGtUN+GbkV1px3T6XdUHmgJ+ldJ1hAHdesFzW/wgL0= -go.opentelemetry.io/collector/consumer v1.54.0/go.mod h1:1PC6XINTL9DdT1bwvfMdHE72EB4RWU/WcPemUrhqKN8= -go.opentelemetry.io/collector/consumer/consumertest v0.148.0 h1:ms0HtWMj17tI1Yds0hSuUI5QYpNEqd11AAhwIoUY2HE= -go.opentelemetry.io/collector/consumer/consumertest v0.148.0/go.mod h1:wScw/OzKkf/ZzJn4ToI30OoI1kJiY16WNrcFToXSzK0= -go.opentelemetry.io/collector/consumer/xconsumer v0.148.0 h1:m3b9rY7CLD5Pcge6sSKHIT3OlcPN6xqYsdtVs9oJ528= -go.opentelemetry.io/collector/consumer/xconsumer v0.148.0/go.mod h1:bG+Wz6xmIBl/gHzq1sqvksWXqTLuTX17Wo//zIsdZpw= -go.opentelemetry.io/collector/featuregate v1.54.0 h1:ufo5Hy4Co9pcHVg24hyanm8qFG3TkkYbVyQXPVAbwDc= -go.opentelemetry.io/collector/featuregate v1.54.0/go.mod h1:PS7zY/zaCb28EqciePVwRHVhc3oKortTFXsi3I6ee4g= -go.opentelemetry.io/collector/internal/componentalias v0.148.0 h1:Y6MftNIZSzOr47TTj6A2z2UR3IwbeG46sAQshicGtDg= -go.opentelemetry.io/collector/internal/componentalias v0.148.0/go.mod h1:uwKzfehzwRgHxdHgFXYSBHNBeWSSqsqQYGWr5fk08G0= -go.opentelemetry.io/collector/internal/testutil v0.148.0 h1:3Z9hperte3vSmbBTYeNndoEUICICrNz8hzx+v0FYXBQ= -go.opentelemetry.io/collector/internal/testutil v0.148.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= -go.opentelemetry.io/collector/pdata v1.54.0 h1:3LharKb792cQ3VrUGxd3IcpWwfu3ST+GSTU382jVz1s= -go.opentelemetry.io/collector/pdata v1.54.0/go.mod h1:+MqC3VVOv/EX9YVFUo+mI4F0YmwJ+fXBYwjmu+mRiZ8= -go.opentelemetry.io/collector/pdata/pprofile v0.148.0 h1:MgrNZmqwhZGfiYwcKKtM/iXgTZqqvG5dUphriRXMZHU= -go.opentelemetry.io/collector/pdata/pprofile v0.148.0/go.mod h1:MTTMnZPqWX1S/rBDatU0W19udlycBkWuzVV5qnemHdc= -go.opentelemetry.io/collector/pdata/testdata v0.148.0 h1:yzakPuFgoKK8WcrlhyYHLMLA/kLScQKGsXkIgwieAQ8= -go.opentelemetry.io/collector/pdata/testdata v0.148.0/go.mod h1:2rFvxm8qwd3nlO90FtJw6ZGAjt+bLndxmQuJaMO9kfQ= -go.opentelemetry.io/collector/pipeline v1.54.0 h1:jYlCkdFLITVBdeB+IGS07zXWywEgvT3Ky46vdKKT+Ks= -go.opentelemetry.io/collector/pipeline v1.54.0/go.mod h1:RD90NG3Jbk965Xaqym3JyHkuol4uZJjQVUkD9ddXJIs= -go.opentelemetry.io/collector/processor v1.54.0 h1:zmHBFiEFmU9ZYuHhVP3lHIkbfy+ueapzGpTdXVMcWBg= -go.opentelemetry.io/collector/processor v1.54.0/go.mod h1:L0lA6DZ0VbrtQBg44cmYfSpRlgm4zxW1I6QfBnRizPw= -go.opentelemetry.io/collector/processor/processortest v0.148.0 h1:p0k59frZxy/Z4fXe82i5eOJv/UyOH75XhI8nFD1ZWCE= -go.opentelemetry.io/collector/processor/processortest v0.148.0/go.mod h1:E2Li2gnkUXgvApvGyEtn3Eq5KyzV05ljfbFRsZ7sTC4= -go.opentelemetry.io/collector/processor/xprocessor v0.148.0 h1:v7Qv6k2b2cvgGWuTO5KN5QYDLl1r5sznt7Le4Fhpa4c= -go.opentelemetry.io/collector/processor/xprocessor v0.148.0/go.mod h1:r7ADpSX2nf0rZR9STxh956Qw1740QOWMXLnEM/ZiaF8= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.67.0 h1:c9r/G1CSw4dPI1jaNNG9RnQP+q4SvZnHciDQJVIvchU= -go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.67.0/go.mod h1:gO9smoZe9KnZcJCqcB0lMmQ4Z5VEifYmjMTpnwtTSuQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0 h1:zWWrB1U6nqhS/k6zYB74CjRpuiitRtLLi68VcgmOEto= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 h1:uLXP+3mghfMf7XmV4PkGfFhFKuNWoCvvx5wP/wOXo0o= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0/go.mod h1:v0Tj04armyT59mnURNUJf7RCKcKzq+lgJs6QSjHjaTc= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= -go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.opentelemetry.io/collector/component v1.57.0 h1:WKIqx2Bs0JaAZxDEhsLradXpYxnwAxVFzWhQUmu2q3w= +go.opentelemetry.io/collector/component v1.57.0/go.mod h1:rXLy5mV78e7Gqp/dzFB+nbAFSEuJCipJfp8LbkrvOMg= +go.opentelemetry.io/collector/component/componentstatus v0.151.0 h1:S2L2y/r+MrqSR8CG/SpbN4WbbUQC5sK+1VgBR2rN660= +go.opentelemetry.io/collector/component/componentstatus v0.151.0/go.mod h1:cDj64a2MAE/pWA1x/jR+oYZQ0d4LBYHcxxONYuijREE= +go.opentelemetry.io/collector/component/componenttest v0.151.0 h1:0rYcx913VAfD1VyVA9MKPjTrdinUaJGEaOhom8MX5zY= +go.opentelemetry.io/collector/component/componenttest v0.151.0/go.mod h1:vmhG58+J9QHOHaNu8LUD5d13LqldvkzI2jil4+lk+x0= +go.opentelemetry.io/collector/confmap v1.57.0 h1:5AuK920dJmV8zxQAiODi2JHPl2r1HmEHHMaBSC+qF5I= +go.opentelemetry.io/collector/confmap v1.57.0/go.mod h1:ifmog4kqEMM037qX04qEbom5CcxhmkadLUqhi2Vkuec= +go.opentelemetry.io/collector/confmap/xconfmap v0.151.0 h1:txpp8lH/J2sKsQXEmV0TXTIrDS7n0Bo2bPJR+mhcP3M= +go.opentelemetry.io/collector/confmap/xconfmap v0.151.0/go.mod h1:3R0Ru3Gsz6HKzjMecZPlTFDzFxaxAOl23ptm+xlsAA0= +go.opentelemetry.io/collector/consumer v1.57.0 h1:jyDh4GkYPuIXNB0UJIh33NAzZoTCVNkwS+XWdlI08P8= +go.opentelemetry.io/collector/consumer v1.57.0/go.mod h1:tJKbog9Xw/8y66aWd/C+21BMuQkOWn/lF4bzJDRC9OM= +go.opentelemetry.io/collector/consumer/consumertest v0.151.0 h1:qByIVlFh9RAR/newAk/sN5i1zoIXKa2K1hRNVfye8LU= +go.opentelemetry.io/collector/consumer/consumertest v0.151.0/go.mod h1:eAGCGxkq+aABLmlr3PvMOqz3ZJbmn/lUqCbbffabSi4= +go.opentelemetry.io/collector/consumer/xconsumer v0.151.0 h1:eKIYxuPBEIrjZMAkyKBUWrlpHAE9OgxXBjq7PMSeXkE= +go.opentelemetry.io/collector/consumer/xconsumer v0.151.0/go.mod h1:9K97TkCN7XYfwKzPzktozrWc3Qw/4A1T4XgMn9TnG0c= +go.opentelemetry.io/collector/featuregate v1.57.0 h1:KPDSUKYn6MHwgyGRSGPPcW/G96HH93pxuvvPwM+R8nY= +go.opentelemetry.io/collector/featuregate v1.57.0/go.mod h1:4ga1QBMPEejXXmpyJS8lmaRpknJ3Lb9Bvk6e420bUFU= +go.opentelemetry.io/collector/internal/componentalias v0.151.0 h1:5IJn4XXRbjGrJCuIByHzxgHqwC0Hcl99tM+PoyYzjJY= +go.opentelemetry.io/collector/internal/componentalias v0.151.0/go.mod h1:c70sQuXHQZWSYCyc0y/VynqJdmEeBunSmEy3xfLQPWE= +go.opentelemetry.io/collector/internal/testutil v0.151.0 h1:CFjDItLuqzblItOsnK6IPSdrsOaZCaDjYpB8qWG+XHI= +go.opentelemetry.io/collector/internal/testutil v0.151.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= +go.opentelemetry.io/collector/pdata v1.57.0 h1:oDWBMjEIqyJO3GJEB+iwqxj47rxDK19OKzwaFEaE4sg= +go.opentelemetry.io/collector/pdata v1.57.0/go.mod h1:wZojinP6mNhLXudH8QXx/bjWzOsKMxi/FXwnk+12G/w= +go.opentelemetry.io/collector/pdata/pprofile v0.151.0 h1:hsU0+DpkvhJh3xL1Y8CX2vAPdLMoJLiw+C+rAMsaxZc= +go.opentelemetry.io/collector/pdata/pprofile v0.151.0/go.mod h1:5zfGTQqRuaKyh2SRaZi4SV4nSD8TzY1kYoOjniOD3uk= +go.opentelemetry.io/collector/pdata/testdata v0.151.0 h1:ye09e8UMADdVrQjLgCznZxmM8ra7ciAuOCteHDzgHjc= +go.opentelemetry.io/collector/pdata/testdata v0.151.0/go.mod h1:h5+Ys9F+pf64cGt5cZCDtRsrkOnvjgpcONr8pFA3KBc= +go.opentelemetry.io/collector/pipeline v1.57.0 h1:nlevGN75Vt/Fp0HTaDjZpUHQf5QFA6o2asSmzSoBVkA= +go.opentelemetry.io/collector/pipeline v1.57.0/go.mod h1:RD90NG3Jbk965Xaqym3JyHkuol4uZJjQVUkD9ddXJIs= +go.opentelemetry.io/collector/processor v1.57.0 h1:EyW3f4pvt/gsfM3JKgRn2WZEyknGzZk5TES3FmwNLgg= +go.opentelemetry.io/collector/processor v1.57.0/go.mod h1:EdKVhK9Oj8Cj2EdYqD/rDKdklLcdwpfSM/q6+KZOMbc= +go.opentelemetry.io/collector/processor/processortest v0.151.0 h1:J+7wLfpyO+gE/yfct11Sy1F6e+/KkLe1/gnh6jDbvbE= +go.opentelemetry.io/collector/processor/processortest v0.151.0/go.mod h1:SKl5FdxTH4bsi90E8e1W79Q94Uoh+OfEMq7yoZqUYVE= +go.opentelemetry.io/collector/processor/xprocessor v0.151.0 h1:TQhnUOP1vbdQ7zKD7SXfjtpthnfwWg23r8a6yeXDN84= +go.opentelemetry.io/collector/processor/xprocessor v0.151.0/go.mod h1:36fKMHBSieF/Se9ErxfNJkMP40IkwerFcuVwG8oF/n0= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0 h1:cuXaPAfIoJKsYjBjPSb2nKZEmgM43zVr25l37IxhKME= +go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.68.0/go.mod h1:BuzhPofpCzlDi/Q/Xjg54M4/3oWqqyDe2Zeq7A2I0QE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 h1:CqXxU8VOmDefoh0+ztfGaymYbhdB/tT3zs79QaZTNGY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0/go.mod h1:BuhAPThV8PBHBvg8ZzZ/Ok3idOdhWIodywz2xEcRbJo= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bTWkw0ICGcOLCAI5l6zsD1j20k= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 h1:RAE+JPfvEmvy+0LzyUA25/SGawPwIUbZ6u0Wug54sLc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0/go.mod h1:AGmbycVGEsRx9mXMZ75CsOyhSP6MFIcj/6dnG+vhVjk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= @@ -644,8 +644,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= -go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= +go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= @@ -659,16 +659,16 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -682,8 +682,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -726,15 +726,15 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -743,8 +743,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -754,26 +754,26 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk= golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/api v0.272.0 h1:eLUQZGnAS3OHn31URRf9sAmRk3w2JjMx37d2k8AjJmA= -google.golang.org/api v0.272.0/go.mod h1:wKjowi5LNJc5qarNvDCvNQBn3rVK8nSy6jg2SwRwzIA= -google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d h1:vsOm753cOAMkt76efriTCDKjpCbK18XGHMJHo0JUKhc= -google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:0oz9d7g9QLSdv9/lgbIjowW1JoxMbxmBVNe8i6tORJI= -google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI= -google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c h1:xgCzyF2LFIO/0X2UAoVRiXKU5Xg6VjToG4i2/ecSswk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/api v0.278.0 h1:W7jiRvRi53VYFfZ/HoZjQBtJk7gOFbHD8ot1RzVZU6E= +google.golang.org/api v0.278.0/go.mod h1:B9TqLBwJqVjp1mtt7WeoQwWRwvu/400y5lETOql+giQ= +google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0= +google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= +google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348 h1:U8orV30l6KpDsi9dxU0CoJZGbjS8EEpw+6ba+XwGPQA= +google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348/go.mod h1:Yzdzr5OOZFgSsEV2D/Xi9NL3bszpXFAg0hFJiRohcD8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 h1:tEkOQcXgF6dH1G+MVKZrfpYvozGrzb91k6ha7jireSM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw= +google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -787,8 +787,8 @@ gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnf gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.67.1 h1:tVBILHy0R6e4wkYOn3XmiITt/hEVH4TFMYvAX2Ytz6k= -gopkg.in/ini.v1 v1.67.1/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= +gopkg.in/ini.v1 v1.67.2 h1:JtOSMb9OuaCZKr7h5D/h6iii14sK0hLbplTc6frx4Ss= +gopkg.in/ini.v1 v1.67.2/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/internal/tools/go.mod b/internal/tools/go.mod index 993ec1f2e5..f95dfd1cb3 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -6,7 +6,7 @@ require ( github.com/bufbuild/buf v1.65.0 github.com/daixiang0/gci v0.14.0 github.com/gogo/protobuf v1.3.2 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 ) require ( @@ -37,13 +37,14 @@ require ( github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect + github.com/creack/pty v1.1.24 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/cli v29.3.0+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker v28.5.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.9.5 // indirect - github.com/docker/go-connections v0.6.0 // indirect + github.com/docker/go-connections v0.7.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-chi/chi/v5 v5.2.4 // indirect @@ -56,7 +57,7 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jdx/go-netrc v1.0.0 // indirect - github.com/klauspost/compress v1.18.5 // indirect + github.com/klauspost/compress v1.18.6 // indirect github.com/klauspost/pgzip v1.2.6 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -87,30 +88,30 @@ require ( go.lsp.dev/protocol v0.12.0 // indirect go.lsp.dev/uri v0.3.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect - go.opentelemetry.io/otel v1.42.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 // indirect - go.opentelemetry.io/otel/metric v1.42.0 // indirect - go.opentelemetry.io/otel/trace v1.42.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect go.uber.org/mock v0.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.1 // indirect + go.uber.org/zap v1.28.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.49.0 // indirect + golang.org/x/crypto v0.50.0 // indirect golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect - golang.org/x/mod v0.33.0 // indirect - golang.org/x/net v0.52.0 // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/net v0.53.0 // indirect golang.org/x/sync v0.20.0 // indirect - golang.org/x/sys v0.42.0 // indirect - golang.org/x/term v0.41.0 // indirect - golang.org/x/text v0.35.0 // indirect + golang.org/x/sys v0.44.0 // indirect + golang.org/x/term v0.42.0 // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c // indirect - google.golang.org/grpc v1.79.3 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 // indirect + google.golang.org/grpc v1.81.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gotest.tools/v3 v3.5.1 // indirect + gotest.tools/v3 v3.5.2 // indirect mvdan.cc/xurls/v2 v2.6.0 // indirect pluginrpc.com/pluginrpc v0.5.0 // indirect ) diff --git a/internal/tools/go.sum b/internal/tools/go.sum index 8f62bd5d20..9a39953fb3 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -65,8 +65,8 @@ github.com/containerd/stargz-snapshotter/estargz v0.18.2/go.mod h1:XyVU5tcJ3PRpk github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= +github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/daixiang0/gci v0.14.0 h1:h6AcLqmjIOBgojhtzY2CvBnA6RawPTkBHgtMvYD5YZ8= github.com/daixiang0/gci v0.14.0/go.mod h1:w9E+SWQ4aPQ+xYPUdqitGDoXpT4mayqOfk7Szz2U6wQ= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -81,8 +81,8 @@ github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaft github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY= github.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c= -github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= -github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= +github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c= +github.com/docker/go-connections v0.7.0/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -107,8 +107,8 @@ github.com/google/go-containerregistry v0.20.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4p github.com/google/go-containerregistry v0.20.7/go.mod h1:Lx5LCZQjLH1QBaMPeGwsME9biPeo1lPx6lbGj/UmzgM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -119,8 +119,8 @@ github.com/jhump/protoreflect/v2 v2.0.0-beta.2 h1:qZU+rEZUOYTz1Bnhi3xbwn+VxdXkLV github.com/jhump/protoreflect/v2 v2.0.0-beta.2/go.mod h1:4tnOYkB/mq7QTyS3YKtVtNrJv4Psqout8HA1U+hZtgM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= -github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= +github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -200,51 +200,51 @@ go.lsp.dev/uri v0.3.0 h1:KcZJmh6nFIBeJzTugn5JTU6OOyG0lDOo3R9KwTxTYbo= go.lsp.dev/uri v0.3.0/go.mod h1:P5sbO1IQR+qySTWOCnhnK7phBx+W3zbLqSMDJNTw88I= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 h1:THuZiwpQZuHPul65w4WcwEnkX2QIuMT+UFoOrygtoJw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0/go.mod h1:J2pvYM5NGHofZ2/Ru6zw/TNWnEQp5crgyDeSrYpXkAw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 h1:uLXP+3mghfMf7XmV4PkGfFhFKuNWoCvvx5wP/wOXo0o= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0/go.mod h1:v0Tj04armyT59mnURNUJf7RCKcKzq+lgJs6QSjHjaTc= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/sdk v1.42.0 h1:LyC8+jqk6UJwdrI/8VydAq/hvkFKNHZVIWuslJXYsDo= -go.opentelemetry.io/otel/sdk v1.42.0/go.mod h1:rGHCAxd9DAph0joO4W6OPwxjNTYWghRWmkHuGbayMts= -go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9RKCAZ3YGuA= -go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= -go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 h1:CqXxU8VOmDefoh0+ztfGaymYbhdB/tT3zs79QaZTNGY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0/go.mod h1:BuhAPThV8PBHBvg8ZzZ/Ok3idOdhWIodywz2xEcRbJo= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bTWkw0ICGcOLCAI5l6zsD1j20k= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= -go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= +go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -255,32 +255,32 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI= -google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c h1:xgCzyF2LFIO/0X2UAoVRiXKU5Xg6VjToG4i2/ecSswk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348 h1:U8orV30l6KpDsi9dxU0CoJZGbjS8EEpw+6ba+XwGPQA= +google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348/go.mod h1:Yzdzr5OOZFgSsEV2D/Xi9NL3bszpXFAg0hFJiRohcD8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 h1:tEkOQcXgF6dH1G+MVKZrfpYvozGrzb91k6ha7jireSM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw= +google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -288,8 +288,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= mvdan.cc/xurls/v2 v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI= mvdan.cc/xurls/v2 v2.6.0/go.mod h1:bCvEZ1XvdA6wDnxY7jPPjEmigDtvtvPXAD/Exa9IMSk= pluginrpc.com/pluginrpc v0.5.0 h1:tOQj2D35hOmvHyPu8e7ohW2/QvAnEtKscy2IJYWQ2yo= diff --git a/web/ui/mantine-ui/src/promql/tools/go.mod b/web/ui/mantine-ui/src/promql/tools/go.mod index 1f240d9aed..c828db4f23 100644 --- a/web/ui/mantine-ui/src/promql/tools/go.mod +++ b/web/ui/mantine-ui/src/promql/tools/go.mod @@ -9,18 +9,29 @@ require ( ) require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 // indirect + github.com/aws/aws-sdk-go-v2 v1.41.7 // indirect + github.com/aws/aws-sdk-go-v2/config v1.32.17 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.16 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dennwc/varint v1.0.0 // indirect + github.com/klauspost/compress v1.18.6 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/prometheus/client_golang v1.23.2 // indirect + github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303 // indirect github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.67.5 // indirect github.com/prometheus/procfs v0.16.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - golang.org/x/sys v0.42.0 // indirect - golang.org/x/text v0.35.0 // indirect + golang.org/x/net v0.53.0 // indirect + golang.org/x/sys v0.44.0 // indirect + golang.org/x/text v0.37.0 // indirect + google.golang.org/api v0.278.0 // indirect + google.golang.org/grpc v1.81.0 // indirect google.golang.org/protobuf v1.36.11 // indirect ) diff --git a/web/ui/mantine-ui/src/promql/tools/go.sum b/web/ui/mantine-ui/src/promql/tools/go.sum index cd2e27d653..0a0db2a011 100644 --- a/web/ui/mantine-ui/src/promql/tools/go.sum +++ b/web/ui/mantine-ui/src/promql/tools/go.sum @@ -1,47 +1,47 @@ -cloud.google.com/go/auth v0.18.2 h1:+Nbt5Ev0xEqxlNjd6c+yYUeosQ5TtEUaNcN/3FozlaM= -cloud.google.com/go/auth v0.18.2/go.mod h1:xD+oY7gcahcu7G2SG2DsBerfFxgPAJz17zz2joOFF3M= +cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA= +cloud.google.com/go/auth v0.20.0/go.mod h1:942/yi/itH1SsmpyrbnTMDgGfdy2BUqIKyd0cyYLc5Q= cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0 h1:fou+2+WFTib47nS+nz/ozhEBnvU96bKHy6LjRsY4E28= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0/go.mod h1:t76Ruy8AHvUAC8GfMWJMa0ElSbuIcO03NLpynfbgsPA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1 h1:jHb/wfvRikGdxMXYV3QG/SzUOPYN9KEUUuC0Yd0/vC0= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1/go.mod h1:pzBXCYn05zvYIrwLgtK8Ap8QcjRg+0i76tMQdWN6wOk= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1 h1:Hk5QBxZQC1jb2Fwj6mpzme37xbCDdNTxU7O9eb5+LB4= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1/go.mod h1:IYus9qsFobWIc2YVwe/WPjcnyCkPKtnHAqUYeebc8z0= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 h1:fhqpLE3UEXi9lPaBRpQ6XuRW0nU7hgg4zlmZZa+a9q4= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY= github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs= github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0= github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= -github.com/aws/aws-sdk-go-v2 v1.41.4 h1:10f50G7WyU02T56ox1wWXq+zTX9I1zxG46HYuG1hH/k= -github.com/aws/aws-sdk-go-v2 v1.41.4/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= -github.com/aws/aws-sdk-go-v2/config v1.32.12 h1:O3csC7HUGn2895eNrLytOJQdoL2xyJy0iYXhoZ1OmP0= -github.com/aws/aws-sdk-go-v2/config v1.32.12/go.mod h1:96zTvoOFR4FURjI+/5wY1vc1ABceROO4lWgWJuxgy0g= -github.com/aws/aws-sdk-go-v2/credentials v1.19.12 h1:oqtA6v+y5fZg//tcTWahyN9PEn5eDU/Wpvc2+kJ4aY8= -github.com/aws/aws-sdk-go-v2/credentials v1.19.12/go.mod h1:U3R1RtSHx6NB0DvEQFGyf/0sbrpJrluENHdPy1j/3TE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20 h1:zOgq3uezl5nznfoK3ODuqbhVg1JzAGDUhXOsU0IDCAo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20/go.mod h1:z/MVwUARehy6GAg/yQ1GO2IMl0k++cu1ohP9zo887wE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 h1:CNXO7mvgThFGqOFgbNAP2nol2qAWBOGfqR/7tQlvLmc= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20/go.mod h1:oydPDJKcfMhgfcgBUZaG+toBbwy8yPWubJXBVERtI4o= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 h1:tN6W/hg+pkM+tf9XDkWUbDEjGLb+raoBMFsTodcoYKw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20/go.mod h1:YJ898MhD067hSHA6xYCx5ts/jEd8BSOLtQDL3iZsvbc= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 h1:2HvVAIq+YqgGotK6EkMf+KIEqTISmTYh5zLpYyeTo1Y= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20/go.mod h1:V4X406Y666khGa8ghKmphma/7C0DAtEQYhkq9z4vpbk= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.8 h1:0GFOLzEbOyZABS3PhYfBIx2rNBACYcKty+XGkTgw1ow= -github.com/aws/aws-sdk-go-v2/service/signin v1.0.8/go.mod h1:LXypKvk85AROkKhOG6/YEcHFPoX+prKTowKnVdcaIxE= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.13 h1:kiIDLZ005EcKomYYITtfsjn7dtOwHDOFy7IbPXKek2o= -github.com/aws/aws-sdk-go-v2/service/sso v1.30.13/go.mod h1:2h/xGEowcW/g38g06g3KpRWDlT+OTfxxI0o1KqayAB8= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 h1:jzKAXIlhZhJbnYwHbvUQZEB8KfgAEuG0dc08Bkda7NU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17/go.mod h1:Al9fFsXjv4KfbzQHGe6V4NZSZQXecFcvaIF4e70FoRA= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 h1:Cng+OOwCHmFljXIxpEVXAGMnBia8MSU6Ch5i9PgBkcU= -github.com/aws/aws-sdk-go-v2/service/sts v1.41.9/go.mod h1:LrlIndBDdjA/EeXeyNBle+gyCwTlizzW5ycgWnvIxkk= -github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= -github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/aws/aws-sdk-go-v2 v1.41.7 h1:DWpAJt66FmnnaRIOT/8ASTucrvuDPZASqhhLey6tLY8= +github.com/aws/aws-sdk-go-v2 v1.41.7/go.mod h1:4LAfZOPHNVNQEckOACQx60Y8pSRjIkNZQz1w92xpMJc= +github.com/aws/aws-sdk-go-v2/config v1.32.17 h1:FpL4/758/diKwqbytU0prpuiu60fgXKUWCpDJtApclU= +github.com/aws/aws-sdk-go-v2/config v1.32.17/go.mod h1:OXqUMzgXytfoF9JaKkhrOYsyh72t9G+MJH8mMRaexOE= +github.com/aws/aws-sdk-go-v2/credentials v1.19.16 h1:r3RJBuU7X9ibt8RHbMjWE6y60QbKBiII6wSrXnapxSU= +github.com/aws/aws-sdk-go-v2/credentials v1.19.16/go.mod h1:6cx7zqDENJDbBIIWX6P8s0h6hqHC8Avbjh9Dseo27ug= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23 h1:UuSfcORqNSz/ey3VPRS8TcVH2Ikf0/sC+Hdj400QI6U= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.23/go.mod h1:+G/OSGiOFnSOkYloKj/9M35s74LgVAdJBSD5lsFfqKg= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23 h1:GpT/TrnBYuE5gan2cZbTtvP+JlHsutdmlV2YfEyNde0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.23/go.mod h1:xYWD6BS9ywC5bS3sz9Xh04whO/hzK2plt2Zkyrp4JuA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 h1:bpd8vxhlQi2r1hiueOw02f/duEPTMK59Q4QMAoTTtTo= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23/go.mod h1:15DfR2nw+CRHIk0tqNyifu3G1YdAOy68RftkhMDDwYk= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 h1:OQqn11BtaYv1WLUowvcA30MpzIu8Ti4pcLPIIyoKZrA= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24/go.mod h1:X5ZJyfwVrWA96GzPmUCWFQaEARPR7gCrpq2E92PJwAE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9 h1:FLudkZLt5ci0ozzgkVo8BJGwvqNaZbTWb3UcucAateA= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.9/go.mod h1:w7wZ/s9qK7c8g4al+UyoF1Sp/Z45UwMGcqIzLWVQHWk= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23 h1:pbrxO/kuIwgEsOPLkaHu0O+m4fNgLU8B3vxQ+72jTPw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.23/go.mod h1:/CMNUqoj46HpS3MNRDEDIwcgEnrtZlKRaHNaHxIFpNA= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.11 h1:TdJ+HdzOBhU8+iVAOGUTU63VXopcumCOF1paFulHWZc= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.11/go.mod h1:R82ZRExE/nheo0N+T8zHPcLRTcH8MGsnR3BiVGX0TwI= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.17 h1:7byT8HUWrgoRp6sXjxtZwgOKfhss5fW6SkLBtqzgRoE= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.17/go.mod h1:xNWknVi4Ezm1vg1QsB/5EWpAJURq22uqd38U8qKvOJc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21 h1:+1Kl1zx6bWi4X7cKi3VYh29h8BvsCoHQEQ6ST9X8w7w= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.21/go.mod h1:4vIRDq+CJB2xFAXZ+YgGUTiEft7oAQlhIs71xcSeuVg= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 h1:F/M5Y9I3nwr2IEpshZgh1GeHpOItExNM9L1euNuh/fk= +github.com/aws/aws-sdk-go-v2/service/sts v1.42.1/go.mod h1:mTNxImtovCOEEuD65mKW7DCsL+2gjEH+RPEAexAzAio= +github.com/aws/smithy-go v1.25.1 h1:J8ERsGSU7d+aCmdQur5Txg6bVoYelvQJgtZehD12GkI= +github.com/aws/smithy-go v1.25.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3 h1:6df1vn4bBlDDo4tARvBm7l6KA9iVMnE3NWizDeWSrps= github.com/bboreham/go-loser v0.0.0-20230920113527-fcc2c21820a3/go.mod h1:CIWtjkly68+yqLPbvwwR/fjNJA/idrtULjZWh2v1ys0= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -68,16 +68,16 @@ github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.3.14 h1:yh8ncqsbUY4shRD5dA6RlzjJaT4hi3kII+zYw8wmLb8= -github.com/googleapis/enterprise-certificate-proxy v0.3.14/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= -github.com/googleapis/gax-go/v2 v2.18.0 h1:jxP5Uuo3bxm3M6gGtV94P4lliVetoCB4Wk2x8QA86LI= -github.com/googleapis/gax-go/v2 v2.18.0/go.mod h1:uSzZN4a356eRG985CzJ3WfbFSpqkLTjsnhWGJR6EwrE= +github.com/googleapis/enterprise-certificate-proxy v0.3.15 h1:xolVQTEXusUcAA5UgtyRLjelpFFHWlPQ4XfWGc7MBas= +github.com/googleapis/enterprise-certificate-proxy v0.3.15/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg= +github.com/googleapis/gax-go/v2 v2.22.0 h1:PjIWBpgGIVKGoCXuiCoP64altEJCj3/Ei+kSU5vlZD4= +github.com/googleapis/gax-go/v2 v2.22.0/go.mod h1:irWBbALSr0Sk3qlqb9SyJ1h68WjgeFuiOzI4Rqw5+aY= github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853 h1:cLN4IBkmkYZNnk7EAJ0BHIethd+J6LqxFNw5mSiI2bM= github.com/grafana/regexp v0.0.0-20250905093917-f7b3be9d1853/go.mod h1:+JKpmjMGhpgPL+rXZ5nsZieVzvarn86asRlBg4uNGnk= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= -github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= +github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -92,8 +92,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= -github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856 h1:1Y6bmpZb8peQCy1IpctnAhIFuyhrdtMaDnETChhSNns= -github.com/prometheus/client_golang/exp v0.0.0-20260325093428-d8591d0db856/go.mod h1:Vf0QcmVhGqpjLxZOaWrFSep86vchQtJmbztFaMM4f6Q= +github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303 h1:PCg3CbvxfRdQOzkVLL6rdWJS2IkobPyAk7nouqiuA9c= +github.com/prometheus/client_golang/exp v0.0.0-20260506204903-0ac87e14c303/go.mod h1:vW/EVguzbNw6xMRmozJQWbY60/+Zsg0TgVJOSXGx2iI= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= @@ -112,42 +112,42 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= -go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= -go.opentelemetry.io/otel v1.42.0/go.mod h1:lJNsdRMxCUIWuMlVJWzecSMuNjE7dOYyWlqOXWkdqCc= -go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4= -go.opentelemetry.io/otel/metric v1.42.0/go.mod h1:RlUN/7vTU7Ao/diDkEpQpnz3/92J9ko05BIwxYa2SSI= -go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= -go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 h1:CqXxU8VOmDefoh0+ztfGaymYbhdB/tT3zs79QaZTNGY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0/go.mod h1:BuhAPThV8PBHBvg8ZzZ/Ok3idOdhWIodywz2xEcRbJo= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= +golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= -google.golang.org/api v0.272.0 h1:eLUQZGnAS3OHn31URRf9sAmRk3w2JjMx37d2k8AjJmA= -google.golang.org/api v0.272.0/go.mod h1:wKjowi5LNJc5qarNvDCvNQBn3rVK8nSy6jg2SwRwzIA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c h1:xgCzyF2LFIO/0X2UAoVRiXKU5Xg6VjToG4i2/ecSswk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260311181403-84a4fc48630c/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/api v0.278.0 h1:W7jiRvRi53VYFfZ/HoZjQBtJk7gOFbHD8ot1RzVZU6E= +google.golang.org/api v0.278.0/go.mod h1:B9TqLBwJqVjp1mtt7WeoQwWRwvu/400y5lETOql+giQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 h1:tEkOQcXgF6dH1G+MVKZrfpYvozGrzb91k6ha7jireSM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw= +google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From 18acb6c2362101ae01a9828cdad824d9169defe0 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Thu, 16 Apr 2026 13:24:56 +0200 Subject: [PATCH 036/170] promql: support native histograms with smoothed/anchored rate Add native histogram support for the smoothed and anchored rate modifiers (rate, increase, delta). Previously these modifiers only worked with float samples and errored on native histograms. The implementation adds histogram interpolation helpers that mirror the float versions, and a dedicated extendedHistogramRate() function parallel to extendedRate(). The smoothSeries() function for smoothed vector selectors now also handles histogram interpolation. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- promql/engine.go | 92 ++++--- promql/functions.go | 255 +++++++++++++++++- .../promqltest/testdata/extended_vectors.test | 165 ++++++++++++ 3 files changed, 480 insertions(+), 32 deletions(-) diff --git a/promql/engine.go b/promql/engine.go index c4048ae239..46b8f2c971 100644 --- a/promql/engine.go +++ b/promql/engine.go @@ -1717,7 +1717,7 @@ func (ev *evaluator) rangeEvalAgg(ctx context.Context, aggExpr *parser.Aggregate // smoothSeries is a helper function that smooths the series by interpolating the values // based on values before and after the timestamp. -func (ev *evaluator) smoothSeries(series []storage.Series, offset time.Duration) Matrix { +func (ev *evaluator) smoothSeries(series []storage.Series, offset time.Duration, pos posrange.PositionRange) (Matrix, annotations.Annotations) { dur := ev.endTimestamp - ev.startTimestamp it := storage.NewBuffer(dur + 2*durationMilliseconds(ev.lookbackDelta)) @@ -1728,6 +1728,7 @@ func (ev *evaluator) smoothSeries(series []storage.Series, offset time.Duration) var chkIter chunkenc.Iterator mat := make(Matrix, 0, len(series)) + var annos annotations.Annotations for _, s := range series { ss := Series{Metric: s.Labels()} @@ -1749,40 +1750,76 @@ func (ev *evaluator) smoothSeries(series []storage.Series, offset time.Duration) continue } - if len(hists) > 0 { - // TODO: support native histograms. - ev.errorf("smoothed and anchored modifiers do not work with native histograms") + if len(hists) > 0 && len(floats) > 0 { + annos.Add(annotations.NewMixedFloatsHistogramsWarning(s.Labels().Get(labels.MetricName), pos)) + continue } - // Binary search for the first index with T >= dataTS. - i := sort.Search(len(floats), func(i int) bool { return floats[i].T >= dataTS }) + if len(hists) > 0 { + // Binary search for the first histogram index with T >= dataTS. + i := sort.Search(len(hists), func(i int) bool { return hists[i].T >= dataTS }) - switch { - case i < len(floats) && floats[i].T == dataTS: - // Exact match. - ss.Floats = append(ss.Floats, FPoint{F: floats[i].F, T: evalTS}) + switch { + case i < len(hists) && hists[i].T == dataTS: + // Exact match. + ss.Histograms = append(ss.Histograms, HPoint{H: hists[i].H.Copy(), T: evalTS}) - case i > 0 && i < len(floats): - // Interpolate between prev and next. - // TODO: detect if the sample is a counter, based on __type__ or metadata. - prev, next := floats[i-1], floats[i] - val := interpolate(prev, next, dataTS, false) - ss.Floats = append(ss.Floats, FPoint{F: val, T: evalTS}) + case i > 0 && i < len(hists): + // Interpolate between prev and next. + // Use CounterResetHint to determine counter vs gauge: treat as counter + // unless both samples explicitly carry the gauge hint. + prev, next := hists[i-1], hists[i] + if prev.H.UsesCustomBuckets() != next.H.UsesCustomBuckets() { + annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(s.Labels().Get(labels.MetricName), pos)) + continue + } + isCounter := prev.H.CounterResetHint != histogram.GaugeType || next.H.CounterResetHint != histogram.GaugeType + h, err := interpolateHistograms(prev.H, prev.T, next.H, next.T, dataTS, isCounter, &annos, pos) + if err != nil { + annos = annosFromInterpolationError(annos, err, s.Labels().Get(labels.MetricName), pos) + continue + } + ss.Histograms = append(ss.Histograms, HPoint{H: h, T: evalTS}) - case i > 0: - // No next point yet; carry forward previous value. - prev := floats[i-1] - ss.Floats = append(ss.Floats, FPoint{F: prev.F, T: evalTS}) + case i > 0: + // No next point yet; carry forward previous value. + prev := hists[i-1] + ss.Histograms = append(ss.Histograms, HPoint{H: prev.H.Copy(), T: evalTS}) - default: - // i == 0 and floats[0].T > dataTS: there is no previous data yet; skip. + default: + // i == 0 and hists[0].T > dataTS: there is no previous data yet; skip. + } + } else { + // Binary search for the first index with T >= dataTS. + i := sort.Search(len(floats), func(i int) bool { return floats[i].T >= dataTS }) + + switch { + case i < len(floats) && floats[i].T == dataTS: + // Exact match. + ss.Floats = append(ss.Floats, FPoint{F: floats[i].F, T: evalTS}) + + case i > 0 && i < len(floats): + // Interpolate between prev and next. + // TODO: detect if the sample is a counter, based on __type__ or metadata. + prev, next := floats[i-1], floats[i] + val := interpolate(prev, next, dataTS, false) + ss.Floats = append(ss.Floats, FPoint{F: val, T: evalTS}) + + case i > 0: + // No next point yet; carry forward previous value. + prev := floats[i-1] + ss.Floats = append(ss.Floats, FPoint{F: prev.F, T: evalTS}) + + default: + // i == 0 and floats[0].T > dataTS: there is no previous data yet; skip. + } } } mat = append(mat, ss) } - return mat + return mat, annos } // evalSeries generates a Matrix between ev.startTimestamp and ev.endTimestamp (inclusive), each point spaced ev.interval apart, from series given offset. @@ -2178,12 +2215,6 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, if len(floats)+len(histograms) == 0 { continue } - if selVS.Anchored || selVS.Smoothed { - if len(histograms) > 0 { - // TODO: support native histograms. - ev.errorf("smoothed and anchored modifiers do not work with native histograms") - } - } inMatrix[0].Floats = floats inMatrix[0].Histograms = histograms enh.Ts = ts @@ -2378,7 +2409,8 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, ev.error(errWithWarnings{fmt.Errorf("expanding series: %w", err), ws}) } if e.Smoothed { - mat := ev.smoothSeries(e.Series, e.Offset) + mat, smoothAnnos := ev.smoothSeries(e.Series, e.Offset, e.PositionRange()) + ws.Merge(smoothAnnos) return mat, ws } mat := ev.evalSeries(ctx, e.Series, e.Offset, false) diff --git a/promql/functions.go b/promql/functions.go index 5eac9080c1..e5608c37c4 100644 --- a/promql/functions.go +++ b/promql/functions.go @@ -107,6 +107,66 @@ func interpolate(p1, p2 FPoint, t int64, isCounter bool) float64 { return y1 + (y2-y1)*float64(t-p1.T)/float64(p2.T-p1.T) } +// interpolateHistograms performs linear interpolation between two histogram points. +// If isCounter is true and there is a counter reset, it models the counter +// as starting from 0 (post-reset) by returning h2 scaled by the fraction. +// It returns an error if the histograms are incompatible (e.g. mixing +// exponential and custom-bucket schemas). NHCB bucket-bounds reconciliation +// warnings are collected into annos. +func interpolateHistograms(h1 *histogram.FloatHistogram, t1 int64, h2 *histogram.FloatHistogram, t2, t int64, isCounter bool, annos *annotations.Annotations, pos posrange.PositionRange) (*histogram.FloatHistogram, error) { + if t == t1 { + return h1.Copy(), nil + } + if t == t2 { + return h2.Copy(), nil + } + fraction := float64(t-t1) / float64(t2-t1) + + if isCounter && h2.DetectReset(h1) { + // Counter reset: model as starting from zero. + return h2.Copy().Mul(fraction), nil + } + + // Result = H1 + (H2 - H1) * fraction. + delta := h2.Copy() + _, _, nhcbReconciled, err := delta.Sub(h1) + if err != nil { + return nil, err + } + if nhcbReconciled { + annos.Add(annotations.NewMismatchedCustomBucketsHistogramsInfo(pos, annotations.HistogramSub)) + } + delta.Mul(fraction) + _, _, nhcbReconciled, err = delta.Add(h1) + if err != nil { + return nil, err + } + if nhcbReconciled { + annos.Add(annotations.NewMismatchedCustomBucketsHistogramsInfo(pos, annotations.HistogramAdd)) + } + return delta, nil +} + +// pickOrInterpolateLeftHistogram returns the histogram at the left boundary of the range. +// If interpolation is needed (when smoothed is true and the first sample is before the range start), +// it returns the interpolated histogram at the left boundary; otherwise, it returns a copy of the first sample's histogram. +func pickOrInterpolateLeftHistogram(hists []HPoint, first int, rangeStart int64, smoothed, isCounter bool, annos *annotations.Annotations, pos posrange.PositionRange) (*histogram.FloatHistogram, error) { + if smoothed && hists[first].T < rangeStart { + return interpolateHistograms(hists[first].H, hists[first].T, hists[first+1].H, hists[first+1].T, rangeStart, isCounter, annos, pos) + } + return hists[first].H.Copy(), nil +} + +// pickOrInterpolateRightHistogram returns the histogram at the right boundary of the range. +// If interpolation is needed (when smoothed is true and the last sample is after the range end), +// it returns the interpolated histogram at the right boundary; otherwise, it returns a copy of the last sample's histogram. +func pickOrInterpolateRightHistogram(hists []HPoint, last int, rangeEnd int64, smoothed, isCounter bool, annos *annotations.Annotations, pos posrange.PositionRange) (*histogram.FloatHistogram, error) { + if smoothed && last > 0 && hists[last].T > rangeEnd { + return interpolateHistograms(hists[last-1].H, hists[last-1].T, hists[last].H, hists[last].T, rangeEnd, isCounter, annos, pos) + } + return hists[last].H.Copy(), nil +} + // correctForCounterResets calculates the correction for counter resets. // This function is only used for extendedRate functions with smoothed or anchored rates. func correctForCounterResets(left, right float64, points []FPoint) float64 { @@ -124,6 +184,86 @@ func correctForCounterResets(left, right float64, points []FPoint) float64 { return correction } +// annosFromInterpolationError classifies an error returned by +// interpolateHistograms (via pickOrInterpolate*Histogram) into the appropriate +// annotation. If the error is not recognised, annos is returned unchanged. +func annosFromInterpolationError(annos annotations.Annotations, err error, metricName string, pos posrange.PositionRange) annotations.Annotations { + if errors.Is(err, histogram.ErrHistogramsIncompatibleSchema) { + return annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(metricName, pos)) + } + return annos +} + +// addHistogramWithAnnotations adds other into base in place, translating +// histogram errors and bucket-bounds reconciliations into annotations. +// It returns false if the operation failed. +func addHistogramWithAnnotations(base, other *histogram.FloatHistogram, annos *annotations.Annotations, metricName string, pos posrange.PositionRange) bool { + _, _, nhcbBoundsReconciled, err := base.Add(other) + if err != nil { + if errors.Is(err, histogram.ErrHistogramsIncompatibleSchema) { + annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(metricName, pos)) + } + return false + } + if nhcbBoundsReconciled { + annos.Add(annotations.NewMismatchedCustomBucketsHistogramsInfo(pos, annotations.HistogramAdd)) + } + return true +} + +// subHistogramWithAnnotations subtracts other from base in place, translating +// histogram errors and bucket-bounds reconciliations into annotations. +// It returns false if the operation failed. +func subHistogramWithAnnotations(base, other *histogram.FloatHistogram, annos *annotations.Annotations, metricName string, pos posrange.PositionRange) bool { + _, _, nhcbBoundsReconciled, err := base.Sub(other) + if err != nil { + if errors.Is(err, histogram.ErrHistogramsIncompatibleSchema) { + annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(metricName, pos)) + } + return false + } + if nhcbBoundsReconciled { + annos.Add(annotations.NewMismatchedCustomBucketsHistogramsInfo(pos, annotations.HistogramSub)) + } + return true +} + +// correctForCounterResetsHistogram calculates the histogram correction for +// counter resets in points, using left and right as the boundary samples. +// It is only used by extendedHistogramRate. It returns the accumulated +// correction (nil if no resets were detected), any annotations produced, and +// false if combining histograms failed. +func correctForCounterResetsHistogram(left, right *histogram.FloatHistogram, points []HPoint, metricName string, pos posrange.PositionRange) (*histogram.FloatHistogram, annotations.Annotations, bool) { + var ( + correction *histogram.FloatHistogram + annos annotations.Annotations + ) + + addCorrection := func(h *histogram.FloatHistogram) bool { + if correction == nil { + correction = h.Copy() + return true + } + return addHistogramWithAnnotations(correction, h, &annos, metricName, pos) + } + + prev := left + for _, p := range points { + if p.H.DetectReset(prev) { + if !addCorrection(prev) { + return nil, annos, false + } + } + prev = p.H + } + if right.DetectReset(prev) { + if !addCorrection(prev) { + return nil, annos, false + } + } + return correction, annos, true +} + // extendedRate is a utility function for anchored/smoothed rate/increase/delta. // It calculates the rate (allowing for counter resets if isCounter is true), // extrapolates if the first/last sample if needed, and returns @@ -178,18 +318,129 @@ func extendedRate(vals Matrix, args parser.Expressions, enh *EvalNodeHelper, isC return append(enh.Out, Sample{F: resultFloat}), annos } +// extendedHistogramRate is a utility function for anchored/smoothed rate/increase/delta +// with native histograms. It calculates the rate (allowing for counter resets if +// isCounter is true), interpolates at the range boundaries if needed, and returns +// the result as either per-second (if isRate is true) or overall. +func extendedHistogramRate(vals Matrix, args parser.Expressions, enh *EvalNodeHelper, isCounter, isRate bool) (Vector, annotations.Annotations) { + var ( + ms = args[0].(*parser.MatrixSelector) + vs = ms.VectorSelector.(*parser.VectorSelector) + samples = vals[0] + h = samples.Histograms + lastSampleIndex = len(h) - 1 + rangeStart = enh.Ts - durationMilliseconds(ms.Range+vs.Offset) + rangeEnd = enh.Ts - durationMilliseconds(vs.Offset) + annos annotations.Annotations + metricName = getMetricName(samples.Metric) + pos = args[0].PositionRange() + smoothed = vs.Smoothed + ) + + firstSampleIndex := max(0, sort.Search(lastSampleIndex, func(i int) bool { return h[i].T > rangeStart })-1) + if smoothed { + lastSampleIndex = sort.Search(lastSampleIndex, func(i int) bool { return h[i].T >= rangeEnd }) + } + + if h[lastSampleIndex].T <= rangeStart { + return enh.Out, annos + } + if smoothed && h[firstSampleIndex].T > rangeEnd { + return enh.Out, annos + } + + usingCustomBuckets := h[firstSampleIndex].H.UsesCustomBuckets() + for _, p := range h[firstSampleIndex : lastSampleIndex+1] { + if p.H.UsesCustomBuckets() != usingCustomBuckets { + return enh.Out, annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(metricName, pos)) + } + if isCounter && p.H.CounterResetHint == histogram.GaugeType { + annos.Add(annotations.NewNativeHistogramNotCounterWarning(metricName, pos)) + } + } + + left, err := pickOrInterpolateLeftHistogram(h, firstSampleIndex, rangeStart, smoothed, isCounter, &annos, pos) + if err != nil { + return enh.Out, annosFromInterpolationError(annos, err, metricName, pos) + } + right, err := pickOrInterpolateRightHistogram(h, lastSampleIndex, rangeEnd, smoothed, isCounter, &annos, pos) + if err != nil { + return enh.Out, annosFromInterpolationError(annos, err, metricName, pos) + } + + if !isCounter && (left.CounterResetHint != histogram.GaugeType || right.CounterResetHint != histogram.GaugeType) { + annos.Add(annotations.NewNativeHistogramNotGaugeWarning(metricName, pos)) + } + + // Compute result = right - left. + resultHistogram := right.Copy() + if !subHistogramWithAnnotations(resultHistogram, left, &annos, metricName, pos) { + return enh.Out, annos + } + + if isCounter { + leftInterpolationHandledReset := smoothed && h[firstSampleIndex].T < rangeStart && h[firstSampleIndex+1].H.DetectReset(h[firstSampleIndex].H) + + // Always skip firstSampleIndex: it is either already represented by + // left (when h[firstSampleIndex].T >= rangeStart) or by the + // interpolation between h[firstSampleIndex] and h[firstSampleIndex+1] + // (when smoothed). Including it in the correction slice would + // double-count via DetectReset's CounterReset shortcut when + // h[firstSampleIndex].CounterResetHint == CounterReset. + first := firstSampleIndex + 1 + if leftInterpolationHandledReset { + // The reset between h[firstSampleIndex] and h[firstSampleIndex+1] + // is already accounted for by the left boundary interpolation. + first++ + } + last := lastSampleIndex + if h[last].T >= rangeEnd { + last-- + } + + if first <= last { + correction, newAnnos, ok := correctForCounterResetsHistogram(left, right, h[first:last+1], metricName, pos) + annos.Merge(newAnnos) + if !ok { + return enh.Out, annos + } + if correction != nil && !addHistogramWithAnnotations(resultHistogram, correction, &annos, metricName, pos) { + return enh.Out, annos + } + } + } + if isRate { + resultHistogram.Div(ms.Range.Seconds()) + } + + resultHistogram.CounterResetHint = histogram.GaugeType + return append(enh.Out, Sample{H: resultHistogram.Compact(0)}), annos +} + // extrapolatedRate is a utility function for rate/increase/delta. // It calculates the rate (allowing for counter resets if isCounter is true), // extrapolates if the first/last sample is close to the boundary, and returns // the result as either per-second (if isRate is true) or overall. // // Note: If the vector selector is smoothed or anchored, it will use the -// extendedRate function instead. +// extendedRate or extendedHistogramRate function instead. func extrapolatedRate(vals Matrix, args parser.Expressions, enh *EvalNodeHelper, isCounter, isRate bool) (Vector, annotations.Annotations) { ms := args[0].(*parser.MatrixSelector) vs := ms.VectorSelector.(*parser.VectorSelector) if vs.Anchored || vs.Smoothed { - return extendedRate(vals, args, enh, isCounter, isRate) + samples := vals[0] + if len(samples.Histograms) > 0 && len(samples.Floats) > 0 { + var annos annotations.Annotations + return enh.Out, annos.Add(annotations.NewMixedFloatsHistogramsWarning(getMetricName(samples.Metric), args[0].PositionRange())) + } + if len(samples.Histograms) > 0 { + return extendedHistogramRate(vals, args, enh, isCounter, isRate) + } + if len(samples.Floats) > 0 { + return extendedRate(vals, args, enh, isCounter, isRate) + } + // Not enough samples. + return enh.Out, nil } var ( diff --git a/promql/promqltest/testdata/extended_vectors.test b/promql/promqltest/testdata/extended_vectors.test index da7cd29f49..ec8e28f133 100644 --- a/promql/promqltest/testdata/extended_vectors.test +++ b/promql/promqltest/testdata/extended_vectors.test @@ -457,3 +457,168 @@ eval range from 0s to 60s step 15s metric offset -100 smoothed eval range from 0s to 60s step 15s metric offset -100 smoothed + 0 {} 10 11.5 13 14.5 16 + +# Native histogram tests for smoothed/anchored modifiers. +# Simple histogram counter incrementing by count:1, sum:1, buckets:[1] every 15s. +clear +load 15s + hist_counter {{schema:0 count:1 sum:1 buckets:[1] offset:1}}+{{count:1 sum:1 buckets:[1] offset:1}}x7 + +# Standard (non-smoothed/anchored) rate and increase at 50s for reference. +eval instant at 50s histogram_count(rate(hist_counter[1m])) + {} 0.06666666666666667 + +eval instant at 50s histogram_count(increase(hist_counter[1m])) + {} 4 + +# Anchored increase at 50s: left=count:1 (t=0), right=count:4 (t=45), increase=3. +eval instant at 50s histogram_count(increase(hist_counter[1m] anchored)) + {} 3 + +eval instant at 50s histogram_sum(increase(hist_counter[1m] anchored)) + {} 3 + +# Smoothed increase at 50s: left=count:1 (t=0), right interpolated at t=50 +# between count:4 (t=45) and count:5 (t=60), fraction=1/3, right=count:4.333..., +# increase=3.333... +eval instant at 50s histogram_count(increase(hist_counter[1m] smoothed)) + {} 3.333333333333333 + +eval instant at 50s histogram_sum(increase(hist_counter[1m] smoothed)) + {} 3.333333333333333 + +# Smoothed increase at 5s: left=count:1 (t=0, not before rangeStart=-55s), +# right interpolated at t=5 between count:1 (t=0) and count:2 (t=15), +# fraction=1/3, right=count:1.333..., increase=0.333... +eval instant at 5s histogram_count(increase(hist_counter[1m] smoothed)) + {} 0.3333333333333333 + +# Smoothed rate at 50s: increase / 60s. +eval instant at 50s histogram_count(rate(hist_counter[1m] smoothed)) + {} 0.05555555555555555 + +# Anchored increase at 5s: only one sample (t=0) in range, increase from itself is 0. +eval instant at 5s histogram_count(increase(hist_counter[1m] anchored)) + {} 0 + +eval instant at 5s histogram_sum(increase(hist_counter[1m] anchored)) + {} 0 + +# Smoothed delta (non-counter) at 50s: same values as smoothed increase +# for a monotonic series (no counter reset correction needed). +eval instant at 50s histogram_count(delta(hist_counter[1m] smoothed)) + {} 3.333333333333333 + +# Smoothed vector selector interpolation for native histograms. +# At t=7s, interpolate between t=0 (count:1) and t=15 (count:2), fraction=7/15. +eval instant at 7s histogram_count(hist_counter smoothed) + {} 1.4666666666666668 + +# At t=15s, exact match: count:2. +eval instant at 15s histogram_count(hist_counter smoothed) + {} 2 + +# Anchored and smoothed native histogram modifiers with custom buckets. +clear +load 30s + mixed_hist {{schema:0 sum:1 count:1 buckets:[1]}} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}} {{schema:0 sum:5 count:4 buckets:[1 2 1]}} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}} + +# Anchored rate should warn and return no result when the range mixes exponential +# and custom buckets at the boundaries. +eval instant at 1m rate(mixed_hist[1m] anchored) + expect warn msg: PromQL warning: vector contains a mix of histograms with exponential and custom buckets schemas for metric name "mixed_hist" + # Should produce no results. + +# Smoothed rate should warn and return no result when interpolation would cross +# exponential and custom buckets. +eval instant at 45s rate(mixed_hist[1m] smoothed) + expect warn msg: PromQL warning: vector contains a mix of histograms with exponential and custom buckets schemas for metric name "mixed_hist" + # Should produce no results. + +# Anchored increase should still account for resets for custom-bucket histograms. +clear +load 30s + reset_custom_hist {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}} {{schema:-53 sum:4 count:4 custom_values:[5 10] buckets:[4]}} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1] counter_reset_hint:reset}} {{schema:-53 sum:3 count:3 custom_values:[5 10] buckets:[3]}} + +eval instant at 90s histogram_count(increase(reset_custom_hist[90s])) + {} 4.5 + +eval instant at 90s histogram_sum(increase(reset_custom_hist[90s])) + {} 4.5 + +eval instant at 90s histogram_count(increase(reset_custom_hist[90s] anchored)) + {} 6 + +eval instant at 90s histogram_sum(increase(reset_custom_hist[90s] anchored)) + {} 6 + +# A gauge-hint on a middle (non-boundary) sample must trigger the "not a counter" +# warning for rate/increase, matching the behaviour of the non-extended path. +clear +load 30s + mid_gauge_hist {{schema:0 sum:1 count:1 buckets:[1]}} {{schema:0 sum:2 count:2 buckets:[2] counter_reset_hint:gauge}} {{schema:0 sum:3 count:3 buckets:[3]}} + +eval instant at 90s histogram_count(rate(mid_gauge_hist[90s] anchored)) + expect warn msg: PromQL warning: this native histogram metric is not a counter: "mid_gauge_hist" + {} 0.022222222222222223 + +eval instant at 90s histogram_count(increase(mid_gauge_hist[90s] smoothed)) + expect warn msg: PromQL warning: this native histogram metric is not a counter: "mid_gauge_hist" + {} 2 + +# Gauge op on a counter-typed series must warn when a boundary sample lacks the +# gauge hint. +eval instant at 90s histogram_count(delta(mid_gauge_hist[90s] anchored)) + expect warn msg: PromQL warning: this native histogram metric is not a gauge: "mid_gauge_hist" + {} 2 + +# Smoothed rate on a custom-bucket-only series interpolates cleanly. +clear +load 15s + custom_only {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}}+{{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}}x7 + +eval instant at 50s histogram_count(increase(custom_only[1m] smoothed)) + {} 3.333333333333333 + +eval instant at 50s histogram_sum(increase(custom_only[1m] smoothed)) + {} 3.333333333333333 + +# Smoothed vector-selector interpolation for a histogram counter crossing a +# reset. isCounter=true (CounterResetHint != GaugeType), so the reset between +# h[1]=count:10 and h[2]=count:2 (counter_reset_hint:reset) is detected and +# the interpolation models the counter as restarting from zero: +# h[2].Mul(fraction) = count:2 * (5/15) = 0.666... +clear +load 15s + reset_middle {{schema:0 sum:5 count:5 buckets:[5]}} {{schema:0 sum:10 count:10 buckets:[10]}} {{schema:0 sum:2 count:2 buckets:[2] counter_reset_hint:reset}} {{schema:0 sum:6 count:6 buckets:[6]}} + +eval instant at 20s histogram_count(reset_middle smoothed) + {} 0.6666666666666666 + +# Smoothed histogram rate must not double-count the first post-reset sample when +# the left range boundary is interpolated across the reset. +clear +load 10s + reset_boundary _ {{schema:0 sum:396 count:396 buckets:[396] counter_reset_hint:not_reset}} {{schema:0 sum:110 count:110 buckets:[110] counter_reset_hint:reset}} {{schema:0 sum:194 count:194 buckets:[194] counter_reset_hint:not_reset}} + +eval instant at 20s500ms histogram_count(rate(reset_boundary[1s] smoothed)) + {} 9.7 + +# Smoothed vector selector emits MixedExponentialCustomHistogramsWarning and +# produces no result when interpolating between exponential and custom-bucket +# histograms. At t=45s: prev=t=30 (custom), next=t=60 (exp) → skip + warn. +clear +load 30s + smoothed_mix {{schema:0 sum:1 count:1 buckets:[1]}} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}} {{schema:0 sum:5 count:4 buckets:[1 2 1]}} {{schema:-53 sum:1 count:1 custom_values:[5 10] buckets:[1]}} + +eval instant at 45s histogram_count(smoothed_mix smoothed) + expect warn msg: PromQL warning: vector contains a mix of histograms with exponential and custom buckets schemas for metric name "smoothed_mix" + +# Smoothed vector selector must emit a warning and produce no result when the +# lookback window mixes floats and histograms. +clear +load 30s + mixed_types 1 2 {{schema:0 sum:3 count:3 buckets:[3]}} {{schema:0 sum:4 count:4 buckets:[4]}} + +eval instant at 45s sort(mixed_types smoothed) + expect warn msg: PromQL warning: encountered a mix of histograms and floats for metric name "mixed_types" From 3b66ea611f22639695dce78115dc684c2645185f Mon Sep 17 00:00:00 2001 From: SuperQ Date: Mon, 11 May 2026 15:30:25 +0200 Subject: [PATCH 037/170] Run Renovate twice a month Increase the frequency of Renovate to twice a month to keep up various dependencies and avoid large drift. Signed-off-by: SuperQ --- renovate.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/renovate.json b/renovate.json index a2f2c75719..88836931a6 100644 --- a/renovate.json +++ b/renovate.json @@ -12,7 +12,7 @@ "gomodUpdateImportPaths" ], "schedule": [ - "* * 21 * *" + "* * 7,21 * *" ], "timezone": "UTC", "github-actions": { From 129ee0d31786ae020bcadc5535f2889a6fd6924d Mon Sep 17 00:00:00 2001 From: Vilius Pranckaitis Date: Mon, 11 May 2026 16:50:36 +0300 Subject: [PATCH 038/170] PromQL: `resets()` function considers start timestamp resets (#18627) * PromQL: `resets()` function considers start timestamp resets Signed-off-by: vpranckaitis * PR comment Signed-off-by: vpranckaitis --------- Signed-off-by: vpranckaitis --- promql/engine.go | 2 +- promql/functions.go | 26 ++++++++++++++++--- .../promqltest/testdata/start_timestamps.test | 10 +++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/promql/engine.go b/promql/engine.go index c4048ae239..a3e8042ea4 100644 --- a/promql/engine.go +++ b/promql/engine.go @@ -2100,7 +2100,7 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value, var chkIter chunkenc.Iterator var startTimestamps *StartTimestamps - if ev.useStartTimestamps && (e.Func.Name == "rate" || e.Func.Name == "irate" || e.Func.Name == "increase") { + if ev.useStartTimestamps && (e.Func.Name == "rate" || e.Func.Name == "irate" || e.Func.Name == "increase" || e.Func.Name == "resets") { // TODO: consider pooling this. startTimestamps = &StartTimestamps{} } diff --git a/promql/functions.go b/promql/functions.go index 5eac9080c1..aac8221452 100644 --- a/promql/functions.go +++ b/promql/functions.go @@ -1957,41 +1957,61 @@ func funcResets(_ []Vector, matrixVal Matrix, args parser.Expressions, enh *Eval return enh.Out, nil } - var prevSample, curSample Sample + var ( + prevSample, curSample Sample + prevST int64 + floatSTs, histogramSTs []int64 + ) + if sts := enh.StartTimestamps; sts != nil { + floatSTs = sts.Floats + histogramSTs = sts.Histograms + } firstSampleIndex, found := pickFirstSampleIndex(floats, args, enh) if !found { return enh.Out, nil } for iFloat, iHistogram := firstSampleIndex, 0; iFloat < len(floats) || iHistogram < len(histograms); { + var curST int64 switch { // Process a float sample if no histogram sample remains or its timestamp is earlier. // Process a histogram sample if no float sample remains or its timestamp is earlier. case iHistogram >= len(histograms) || iFloat < len(floats) && floats[iFloat].T < histograms[iHistogram].T: + curSample.T = floats[iFloat].T curSample.F = floats[iFloat].F curSample.H = nil + if iFloat < len(floatSTs) { + curST = floatSTs[iFloat] + } iFloat++ case iFloat >= len(floats) || iHistogram < len(histograms) && floats[iFloat].T > histograms[iHistogram].T: + curSample.T = histograms[iHistogram].T curSample.H = histograms[iHistogram].H + if iHistogram < len(histogramSTs) { + curST = histogramSTs[iHistogram] + } iHistogram++ } // Skip the comparison for the first sample, just initialize prevSample. if iFloat+iHistogram == 1+firstSampleIndex { prevSample = curSample + prevST = curST continue } + switch { case prevSample.H == nil && curSample.H == nil: - if curSample.F < prevSample.F { + if curSample.F < prevSample.F || isStartTimestampReset(prevST, prevSample.T, curST, curSample.T) { resets++ } case prevSample.H != nil && curSample.H == nil, prevSample.H == nil && curSample.H != nil: resets++ case prevSample.H != nil && curSample.H != nil: - if curSample.H.DetectReset(prevSample.H) { + if isStartTimestampReset(prevST, prevSample.T, curST, curSample.T) || curSample.H.DetectReset(prevSample.H) { resets++ } } prevSample = curSample + prevST = curST } return append(enh.Out, Sample{F: float64(resets)}), nil diff --git a/promql/promqltest/testdata/start_timestamps.test b/promql/promqltest/testdata/start_timestamps.test index 3ad31e85ba..592254bfc8 100644 --- a/promql/promqltest/testdata/start_timestamps.test +++ b/promql/promqltest/testdata/start_timestamps.test @@ -38,6 +38,12 @@ eval range from 7m to 15m step 1m increase(cumulative[5m:1m]) {type="st_resets"} 300x8 {type="normalized_resets"} 420 780 675 675 1275 900 900 1725 1125 +# Resets function also considers start timestamp resets. +eval range from 7m to 15m step 1m resets(cumulative[5m]) + {type="no_st"} 0x8 + {type="st_resets"} 1 2 1 1 2 1 1 2 1 + {type="normalized_resets"} 0x8 + clear # Tests for rate(), irate() and increase() on deltas. Includes various approaches for start timestamps: @@ -131,6 +137,10 @@ eval range from 7m to 15m step 1m rate(cumulative[5m]) eval range from 7m to 15m step 1m irate(cumulative[5m]) {} {{count:1 sum:1}}x8 +# Resets function also considers start timestamp resets. +eval range from 7m to 15m step 1m resets(cumulative[5m]) + {} 0x8 + clear # Tests for rate(), irate() and increase() on delta histograms. From 9ddc1fe475e527f71c8ee12d56a4fb3cf3aa87e0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 13:59:23 +0000 Subject: [PATCH 039/170] Update github/codeql-action action to v4.35.4 (#18672) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- .github/workflows/scorecards.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9f8a770b99..1c579e52c4 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -28,12 +28,12 @@ jobs: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 + uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 with: languages: ${{ matrix.language }} - name: Autobuild - uses: github/codeql-action/autobuild@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 + uses: github/codeql-action/autobuild@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 + uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index b54be91620..53f50ce638 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -45,6 +45,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4 + uses: github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4 with: sarif_file: results.sarif From 5cf214cf5e3ac61dda69e0e1e706c347a1531eec Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 17:40:29 +0200 Subject: [PATCH 040/170] Update actions/cache action to v5.0.5 (#18670) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c78bc5d86a..3926123d4d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -341,7 +341,7 @@ jobs: with: node-version-file: "web/ui/.nvmrc" registry-url: "https://registry.npmjs.org" - - uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3 + - uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} From 2ac56b3285dfb60d76557e54a13ad57c23a48dd0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 18:10:52 +0200 Subject: [PATCH 041/170] Update actions/setup-node action to v6.4.0 (#18671) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3926123d4d..24baae4d81 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -337,7 +337,7 @@ jobs: with: persist-credentials: false - name: Install nodejs - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version-file: "web/ui/.nvmrc" registry-url: "https://registry.npmjs.org" From a732c0793a8d39432f2fc1df97bebf5e3f99dd6a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 May 2026 18:11:18 +0200 Subject: [PATCH 042/170] Update actions/upload-artifact action to v7 (#18674) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/fuzzing.yml | 2 +- .github/workflows/scorecards.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml index 200fcf418f..1b041e6df0 100644 --- a/.github/workflows/fuzzing.yml +++ b/.github/workflows/fuzzing.yml @@ -27,7 +27,7 @@ jobs: done id: fuzz - name: Upload Crash Artifacts - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 if: failure() with: name: fuzz-artifacts-${{ join(matrix.fuzz_test, '-') }} diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 53f50ce638..a085e174e0 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -37,7 +37,7 @@ jobs: # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF # format to the repository Actions tab. - name: "Upload artifact" - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # tag=v6.0.0 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: SARIF file path: results.sarif From 54d4f527a0a34cd338e0a62214ee3ccd9913c0a3 Mon Sep 17 00:00:00 2001 From: cui Date: Tue, 12 May 2026 21:45:59 +0800 Subject: [PATCH 043/170] textparse: fix NaN canonicalization check in OpenMetrics getFloatValue (#18399) * textparse: fix NaN canonicalization check in OpenMetrics getFloatValue * textparse: add tests for OpenMetrics summary NaN quantiles getFloatValue was testing p.exemplarVal instead of the parsed float when normalizing NaN to the canonical representation, so metric values that were NaN were not normalized correctly. Extend TestOpenMetricsParse with nansum summary lines and cmpopts.EquateNaNs in requireEntries so NaN float values compare equal after canonicalization. Signed-off-by: Weixie Cui Signed-off-by: cui Co-authored-by: George Krajcsovits --- model/textparse/interface_test.go | 1 + model/textparse/openmetricsparse.go | 2 +- model/textparse/openmetricsparse_test.go | 46 +++++++++++++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/model/textparse/interface_test.go b/model/textparse/interface_test.go index d0b6b293a9..6241ea6bb2 100644 --- a/model/textparse/interface_test.go +++ b/model/textparse/interface_test.go @@ -222,6 +222,7 @@ func requireEntries(t *testing.T, exp, got []parsedEntry) { _, yIsLabels := y.(labels.Labels) return !xIsLabels && !yIsLabels }, cmpopts.EquateEmpty()), + cmpopts.EquateNaNs(), cmp.AllowUnexported(parsedEntry{}), }) } diff --git a/model/textparse/openmetricsparse.go b/model/textparse/openmetricsparse.go index 9678d6d152..209a6294ef 100644 --- a/model/textparse/openmetricsparse.go +++ b/model/textparse/openmetricsparse.go @@ -763,7 +763,7 @@ func (p *OpenMetricsParser) getFloatValue(t token, after string) (float64, error return 0, fmt.Errorf("%w while parsing: %q", err, p.l.b[p.start:p.l.i]) } // Ensure canonical NaN value. - if math.IsNaN(p.exemplarVal) { + if math.IsNaN(val) { val = math.Float64frombits(value.NormalNaN) } return val, nil diff --git a/model/textparse/openmetricsparse_test.go b/model/textparse/openmetricsparse_test.go index d365d8d959..db612a74c2 100644 --- a/model/textparse/openmetricsparse_test.go +++ b/model/textparse/openmetricsparse_test.go @@ -16,6 +16,7 @@ package textparse import ( "fmt" "io" + "math" "testing" "github.com/prometheus/common/model" @@ -23,6 +24,7 @@ import ( "github.com/prometheus/prometheus/model/exemplar" "github.com/prometheus/prometheus/model/labels" + "github.com/prometheus/prometheus/model/value" ) func int64p(x int64) *int64 { return &x } @@ -113,7 +115,13 @@ foobar_count 21 foobar_created 1520430004 foobar_sum 324789.6 foobar{quantile="0.95"} 123.8 -foobar{quantile="0.99"} 150.1` +foobar{quantile="0.99"} 150.1 +# HELP nansum Summary with NaN value +# TYPE nansum summary +nansum_count 0 +nansum_sum 0.0 +nansum{quantile="0.95"} nan +nansum{quantile="0.99"} NaN` input += "\n# HELP metric foo\x00bar" input += "\nnull_byte_metric{a=\"abc\x00\"} 1" @@ -631,6 +639,42 @@ foobar{quantile="0.99"} 150.1` labels.FromStrings("__name__", "foobar", "quantile", "0.99"), ), st: 1520430004000, + }, { + m: "nansum", + help: "Summary with NaN value", + }, { + m: "nansum", + typ: model.MetricTypeSummary, + }, { + m: "nansum_count", + lset: typeAndUnitLabels( + typeAndUnitEnabled, + labels.FromStrings("__name__", "nansum_count", "__type__", string(model.MetricTypeSummary)), + labels.FromStrings("__name__", "nansum_count"), + ), + }, { + m: "nansum_sum", + lset: typeAndUnitLabels( + typeAndUnitEnabled, + labels.FromStrings("__name__", "nansum_sum", "__type__", string(model.MetricTypeSummary)), + labels.FromStrings("__name__", "nansum_sum"), + ), + }, { + m: `nansum{quantile="0.95"}`, + v: math.Float64frombits(value.NormalNaN), + lset: typeAndUnitLabels( + typeAndUnitEnabled, + labels.FromStrings("__name__", "nansum", "__type__", string(model.MetricTypeSummary), "quantile", "0.95"), + labels.FromStrings("__name__", "nansum", "quantile", "0.95"), + ), + }, { + m: `nansum{quantile="0.99"}`, + v: math.Float64frombits(value.NormalNaN), + lset: typeAndUnitLabels( + typeAndUnitEnabled, + labels.FromStrings("__name__", "nansum", "__type__", string(model.MetricTypeSummary), "quantile", "0.99"), + labels.FromStrings("__name__", "nansum", "quantile", "0.99"), + ), }, { m: "metric", help: "foo\x00bar", From 9ec9b1e3c64420ef4be77ba7bd51ab429aadc53b Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Tue, 12 May 2026 11:00:12 -0400 Subject: [PATCH 044/170] Comments to explain what's going on Signed-off-by: Owen Williams --- tsdb/head.go | 7 +++++-- tsdb/head_append.go | 8 ++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tsdb/head.go b/tsdb/head.go index 4840f0cae5..5d447698ad 100644 --- a/tsdb/head.go +++ b/tsdb/head.go @@ -73,7 +73,7 @@ type Head struct { numSeries atomic.Uint64 numStaleSeries atomic.Uint64 minOOOTime, maxOOOTime atomic.Int64 // TODO(jesusvazquez) These should be updated after garbage collection. - minTime, maxTime atomic.Int64 // Current min and max of the samples included in the head. TODO(jesusvazquez) Ensure these are properly tracked. + minTime, maxTime atomic.Int64 // Current min and max of the samples included in the head. minTime != math.MaxInt64 is used to determine whether the head has been initialized, so care must be taken that the initialized state only changes after maxTime is already updated. minValidTime atomic.Int64 // Mint allowed to be added to the head. It shouldn't be lower than the maxt of the last persisted block. lastWALTruncationTime atomic.Int64 lastMemoryTruncationTime atomic.Int64 @@ -1139,6 +1139,8 @@ func (h *Head) PostingsCardinalityStats(statsByLabelName string, limit int) *ind return h.cardinalityCache } +// Expands the Head time bounds to include the provided in-order range. +// Concurrent updates retry with compare-and-swap so the bounds only move outward. func (h *Head) updateMinMaxTime(mint, maxt int64) { for { lt := h.MinTime() @@ -1813,7 +1815,8 @@ func (h *Head) Meta() BlockMeta { } } -// MinTime returns the lowest time bound on visible data in the head. +// MinTime returns the lowest time bound on visible data in the head. If this +// value is math.MaxInt64, we consider the head to be uninitialized. func (h *Head) MinTime() int64 { return h.minTime.Load() } diff --git a/tsdb/head_append.go b/tsdb/head_append.go index f2b89653af..30ec7c8302 100644 --- a/tsdb/head_append.go +++ b/tsdb/head_append.go @@ -118,10 +118,10 @@ func (a *initAppender) AppendSTZeroSample(ref storage.SeriesRef, lset labels.Lab // for a completely fresh head with an empty WAL. func (h *Head) initTime(t int64) { // maxTime must be set before minTime, because initialized() keys off minTime. - // If minTime were set first, a concurrent Head.Appender call could observe - // initialized() == true while maxTime is still math.MinInt64; the resulting - // underflow in appendableMinValidTime would reject in-range samples with - // ErrOutOfBounds. + // If minTime were set to t first, a concurrent Head.Appender call could + // observe initialized() == true while maxTime is still math.MinInt64; the + // resulting underflow in appendableMinValidTime would reject in-range samples + // with ErrOutOfBounds. if !h.maxTime.CompareAndSwap(math.MinInt64, t) { // Another goroutine already won the init race. Wait until it also sets // minTime, so callers that next read initialized() can rely on both From b69f991b570cfa3a9998153de9c26cf859b6e8d5 Mon Sep 17 00:00:00 2001 From: Flying Musk Date: Tue, 12 May 2026 15:10:37 -0700 Subject: [PATCH 045/170] ui: improve y-axis tick precision Signed-off-by: Flying Musk --- .../src/pages/query/uPlotChartHelpers.ts | 69 +++++++++++++------ 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/web/ui/mantine-ui/src/pages/query/uPlotChartHelpers.ts b/web/ui/mantine-ui/src/pages/query/uPlotChartHelpers.ts index afb09bfb4b..30b5e2e6be 100644 --- a/web/ui/mantine-ui/src/pages/query/uPlotChartHelpers.ts +++ b/web/ui/mantine-ui/src/pages/query/uPlotChartHelpers.ts @@ -5,54 +5,81 @@ import { getSeriesColor } from "./colorPool"; import { computePosition, shift, flip, offset } from "@floating-ui/dom"; import uPlot, { AlignedData, Series } from "uplot"; -const formatYAxisTickValue = (y: number | null): string => { +const formatYAxisTickValue = (y: number | null, precision = 2): string => { if (y === null) { return "null"; } const absY = Math.abs(y); if (absY >= 1e24) { - return (y / 1e24).toFixed(2) + "Y"; + return (y / 1e24).toFixed(precision) + "Y"; } else if (absY >= 1e21) { - return (y / 1e21).toFixed(2) + "Z"; + return (y / 1e21).toFixed(precision) + "Z"; } else if (absY >= 1e18) { - return (y / 1e18).toFixed(2) + "E"; + return (y / 1e18).toFixed(precision) + "E"; } else if (absY >= 1e15) { - return (y / 1e15).toFixed(2) + "P"; + return (y / 1e15).toFixed(precision) + "P"; } else if (absY >= 1e12) { - return (y / 1e12).toFixed(2) + "T"; + return (y / 1e12).toFixed(precision) + "T"; } else if (absY >= 1e9) { - return (y / 1e9).toFixed(2) + "G"; + return (y / 1e9).toFixed(precision) + "G"; } else if (absY >= 1e6) { - return (y / 1e6).toFixed(2) + "M"; + return (y / 1e6).toFixed(precision) + "M"; } else if (absY >= 1e3) { - return (y / 1e3).toFixed(2) + "k"; + return (y / 1e3).toFixed(precision) + "k"; } else if (absY >= 1) { - return y.toFixed(2); + return y.toFixed(precision); } else if (absY === 0) { - return y.toFixed(2); + return y.toFixed(precision); } else if (absY < 1e-23) { - return (y / 1e-24).toFixed(2) + "y"; + return (y / 1e-24).toFixed(precision) + "y"; } else if (absY < 1e-20) { - return (y / 1e-21).toFixed(2) + "z"; + return (y / 1e-21).toFixed(precision) + "z"; } else if (absY < 1e-17) { - return (y / 1e-18).toFixed(2) + "a"; + return (y / 1e-18).toFixed(precision) + "a"; } else if (absY < 1e-14) { - return (y / 1e-15).toFixed(2) + "f"; + return (y / 1e-15).toFixed(precision) + "f"; } else if (absY < 1e-11) { - return (y / 1e-12).toFixed(2) + "p"; + return (y / 1e-12).toFixed(precision) + "p"; } else if (absY < 1e-8) { - return (y / 1e-9).toFixed(2) + "n"; + return (y / 1e-9).toFixed(precision) + "n"; } else if (absY < 1e-5) { - return (y / 1e-6).toFixed(2) + "µ"; + return (y / 1e-6).toFixed(precision) + "µ"; } else if (absY < 1e-2) { - return (y / 1e-3).toFixed(2) + "m"; + return (y / 1e-3).toFixed(precision) + "m"; } else if (absY <= 1) { - return y.toFixed(2); + return y.toFixed(precision); } throw Error("couldn't format a value, this is a bug"); }; +const maxYAxisTickPrecision = 8; + +const hasDuplicateLabels = (labels: string[]): boolean => + new Set(labels).size !== labels.length; + +const formatYAxisTickValues = (splits: number[]): string[] => { + const labels = splits.map((split) => formatYAxisTickValue(split)); + + if (!hasDuplicateLabels(labels)) { + return labels; + } + + for (let precision = 3; precision <= maxYAxisTickPrecision; precision++) { + const preciseLabels = splits.map((split) => + formatYAxisTickValue(split, precision) + ); + + if (!hasDuplicateLabels(preciseLabels)) { + return preciseLabels; + } + } + + return splits.map((split) => + formatYAxisTickValue(split, maxYAxisTickPrecision) + ); +}; + const escapeHTML = (str: string): string => { const entityMap: { [key: string]: string } = { "&": "&", @@ -383,7 +410,7 @@ export const getUPlotOptions = ( }, // Y axis (sample value). { - values: (_u: uPlot, splits: number[]) => splits.map(formatYAxisTickValue), + values: (_u: uPlot, splits: number[]) => formatYAxisTickValues(splits), ticks: { stroke: light ? "#00000010" : "#ffffff20", }, From 7b29b912e3712cb06e93d3c2db7f77cc2b4fee96 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 13 May 2026 09:29:32 +0200 Subject: [PATCH 046/170] Revert "PromQL: Promote duration expressions as stable" This reverts commit 1463a5bb5a6f837e56f83d83f9f0726804a62e56. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- cmd/prometheus/main.go | 5 +- cmd/prometheus/testdata/features.json | 2 +- cmd/promtool/main.go | 4 +- docs/command-line/prometheus.md | 2 +- docs/command-line/promtool.md | 2 +- docs/feature_flags.md | 57 +++++++++++++++ docs/querying/basics.md | 69 +++---------------- docs/querying/functions.md | 3 +- promql/durations_test.go | 2 +- promql/parser/features.go | 4 +- promql/parser/generated_parser.y | 7 ++ promql/parser/generated_parser.y.go | 7 ++ promql/parser/parse.go | 7 ++ promql/parser/parse_test.go | 2 + promql/parser/prettier_test.go | 2 +- promql/parser/printer_test.go | 1 + promql/promqltest/test.go | 1 + util/fuzzing/fuzz_test.go | 1 + web/ui/mantine-ui/src/promql/functionDocs.tsx | 48 ++++++++----- 19 files changed, 138 insertions(+), 88 deletions(-) diff --git a/cmd/prometheus/main.go b/cmd/prometheus/main.go index fcb655fb1e..6066a5be1d 100644 --- a/cmd/prometheus/main.go +++ b/cmd/prometheus/main.go @@ -260,7 +260,8 @@ func (c *flagConfig) setFeatureListOptions(logger *slog.Logger) error { c.parserOpts.EnableExperimentalFunctions = true logger.Info("Experimental PromQL functions enabled.") case "promql-duration-expr": - logger.Warn("This option for --enable-feature is now permanently enabled and therefore a no-op.", "option", o) + c.parserOpts.ExperimentalDurationExpr = true + logger.Info("Experimental duration expression parsing enabled.") case "native-histograms": logger.Warn("This option for --enable-feature is a no-op. To scrape native histograms, set the scrape_native_histograms scrape config setting to true.", "option", o) case "ooo-native-histograms": @@ -619,7 +620,7 @@ func main() { a.Flag("scrape.discovery-reload-interval", "Interval used by scrape manager to throttle target groups updates."). Hidden().Default("5s").SetValue(&cfg.scrape.DiscoveryReloadInterval) - a.Flag("enable-feature", "Comma separated feature names to enable. Valid options: concurrent-rule-eval, created-timestamp-zero-ingestion, delayed-compaction, exemplar-storage, extra-scrape-metrics, memory-snapshot-on-shutdown, metadata-wal-records, old-ui, otlp-deltatocumulative, otlp-native-delta-ingestion, promql-binop-fill-modifiers, promql-delayed-name-removal, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, st-storage, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details."). + a.Flag("enable-feature", "Comma separated feature names to enable. Valid options: concurrent-rule-eval, created-timestamp-zero-ingestion, delayed-compaction, exemplar-storage, extra-scrape-metrics, memory-snapshot-on-shutdown, metadata-wal-records, old-ui, otlp-deltatocumulative, otlp-native-delta-ingestion, promql-binop-fill-modifiers, promql-delayed-name-removal, promql-duration-expr, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, st-storage, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details."). StringsVar(&cfg.featureList) a.Flag("agent", "Run Prometheus in 'Agent mode'.").BoolVar(&agentMode) diff --git a/cmd/prometheus/testdata/features.json b/cmd/prometheus/testdata/features.json index 90bf375781..78c6b5bdc8 100644 --- a/cmd/prometheus/testdata/features.json +++ b/cmd/prometheus/testdata/features.json @@ -29,7 +29,7 @@ "bool": true, "by": true, "delayed_name_removal": false, - "duration_expr": true, + "duration_expr": false, "fill": false, "fill_left": false, "fill_right": false, diff --git a/cmd/promtool/main.go b/cmd/promtool/main.go index 88ee3be3f7..fbea5eda6a 100644 --- a/cmd/promtool/main.go +++ b/cmd/promtool/main.go @@ -320,7 +320,7 @@ func main() { promQLLabelsDeleteQuery := promQLLabelsDeleteCmd.Arg("query", "PromQL query.").Required().String() promQLLabelsDeleteName := promQLLabelsDeleteCmd.Arg("name", "Name of the label to delete.").Required().String() - featureList := app.Flag("enable-feature", "Comma separated feature names to enable. Valid options: promql-experimental-functions, promql-delayed-name-removal, promql-extended-range-selectors. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details").Default("").Strings() + featureList := app.Flag("enable-feature", "Comma separated feature names to enable. Valid options: promql-experimental-functions, promql-delayed-name-removal, promql-duration-expr, promql-extended-range-selectors. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details").Default("").Strings() documentationCmd := app.Command("write-documentation", "Generate command line documentation. Internal use.").Hidden() @@ -358,7 +358,7 @@ func main() { case "promql-delayed-name-removal": promqlEnableDelayedNameRemoval = true case "promql-duration-expr": - fmt.Printf(" WARNING: promql-duration-expr is now permanently enabled and therefore a no-op") + promtoolParserOpts.ExperimentalDurationExpr = true case "promql-extended-range-selectors": promtoolParserOpts.EnableExtendedRangeSelectors = true case "": diff --git a/docs/command-line/prometheus.md b/docs/command-line/prometheus.md index e21c4c2a67..289ded3842 100644 --- a/docs/command-line/prometheus.md +++ b/docs/command-line/prometheus.md @@ -62,7 +62,7 @@ The Prometheus monitoring server | --query.timeout | Maximum time a query may take before being aborted. Use with server mode only. | `2m` | | --query.max-concurrency | Maximum number of queries executed concurrently. Use with server mode only. | `20` | | --query.max-samples | Maximum number of samples a single query can load into memory. Note that queries will fail if they try to load more samples than this into memory, so this also limits the number of samples a query can return. Use with server mode only. | `50000000` | -| --enable-feature ... | Comma separated feature names to enable. Valid options: concurrent-rule-eval, created-timestamp-zero-ingestion, delayed-compaction, exemplar-storage, extra-scrape-metrics, memory-snapshot-on-shutdown, metadata-wal-records, old-ui, otlp-deltatocumulative, otlp-native-delta-ingestion, promql-binop-fill-modifiers, promql-delayed-name-removal, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, st-storage, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details. | | +| --enable-feature ... | Comma separated feature names to enable. Valid options: concurrent-rule-eval, created-timestamp-zero-ingestion, delayed-compaction, exemplar-storage, extra-scrape-metrics, memory-snapshot-on-shutdown, metadata-wal-records, old-ui, otlp-deltatocumulative, otlp-native-delta-ingestion, promql-binop-fill-modifiers, promql-delayed-name-removal, promql-duration-expr, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, st-storage, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details. | | | --agent | Run Prometheus in 'Agent mode'. | | | --log.level | Only log messages with the given severity or above. One of: [debug, info, warn, error] | `info` | | --log.format | Output format of log messages. One of: [logfmt, json] | `logfmt` | diff --git a/docs/command-line/promtool.md b/docs/command-line/promtool.md index aa606435f8..28a0d99696 100644 --- a/docs/command-line/promtool.md +++ b/docs/command-line/promtool.md @@ -12,7 +12,7 @@ Tooling for the Prometheus monitoring system. | -h, --help | Show context-sensitive help (also try --help-long and --help-man). | | --version | Show application version. | | --experimental | Enable experimental commands. | -| --enable-feature ... | Comma separated feature names to enable. Valid options: promql-experimental-functions, promql-delayed-name-removal, promql-extended-range-selectors. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details | +| --enable-feature ... | Comma separated feature names to enable. Valid options: promql-experimental-functions, promql-delayed-name-removal, promql-duration-expr, promql-extended-range-selectors. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details | diff --git a/docs/feature_flags.md b/docs/feature_flags.md index fddb4dcf6b..2806e4baa7 100644 --- a/docs/feature_flags.md +++ b/docs/feature_flags.md @@ -192,6 +192,63 @@ state is mutex guarded. Cumulative-only OTLP requests are not affected. [d2c]: https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/deltatocumulativeprocessor +## PromQL arithmetic expressions in time durations + +`--enable-feature=promql-duration-expr` + +With this flag, arithmetic expressions can be used in time durations in range queries and offset durations. + +In range queries: +``` +rate(http_requests_total[5m * 2]) # 10 minute range +rate(http_requests_total[(5+2) * 1m]) # 7 minute range +``` + +In offset durations: +``` +http_requests_total offset (1h / 2) # 30 minute offset +http_requests_total offset ((2 ^ 3) * 1m) # 8 minute offset +``` + +When using offset with duration expressions, you must wrap the expression in +parentheses. Without parentheses, only the first duration value will be used in +the offset calculation. + +`step()` can be used in duration expressions. +For a **range query**, it resolves to the step width of the range query. +For an **instant query**, it resolves to `0s`. + +`range()` can be used in duration expressions. +For a **range query**, it resolves to the full range of the query (end time - start time). +For an **instant query**, it resolves to `0s`. +This is particularly useful in combination with `@end()` to look back over the entire query range, e.g., `max_over_time(metric[range()] @ end())`. + +`min(, )` and `max(, )` can be used to find the minimum or maximum of two duration expressions. + +**Note**: Duration expressions are not supported in the @ timestamp operator. + +The following operators are supported: + +* `+` - addition +* `-` - subtraction +* `*` - multiplication +* `/` - division +* `%` - modulo +* `^` - exponentiation + +Examples of equivalent durations: + +* `5m * 2` is equivalent to `10m` or `600s` +* `10m - 1m` is equivalent to `9m` or `540s` +* `(5+2) * 1m` is equivalent to `7m` or `420s` +* `1h / 2` is equivalent to `30m` or `1800s` +* `4h % 3h` is equivalent to `1h` or `3600s` +* `(2 ^ 3) * 1m` is equivalent to `8m` or `480s` +* `step() + 1` is equivalent to the query step width increased by 1s. +* `max(step(), 5s)` is equivalent to the larger of the query step width and `5s`. +* `min(2 * step() + 5s, 5m)` is equivalent to the smaller of twice the query step increased by `5s` and `5m`. + + ## OTLP Native Delta Support `--enable-feature=otlp-native-delta-ingestion` diff --git a/docs/querying/basics.md b/docs/querying/basics.md index c3fcfee432..e7f1173af4 100644 --- a/docs/querying/basics.md +++ b/docs/querying/basics.md @@ -174,57 +174,6 @@ Examples: 12h34m56s # Equivalent to 45296s and thus 45296. 54s321ms # Equivalent to 54.321. -#### Duration expressions - -Duration expressions can be used in range selectors, subquery range and -resolution fields, and offset durations. - -Examples: - - rate(http_requests_total[5m * 2]) # 10 minute range. - rate(http_requests_total[(5 + 2) * 1m]) # 7 minute range. - http_requests_total offset (1h / 2) # 30 minute offset. - http_requests_total offset ((2 ^ 3) * 1m) # 8 minute offset. - -When using offset with duration expressions, you must wrap the expression in -parentheses. Without parentheses, only the first duration value will be used in -the offset calculation. - -`step()` can be used in duration expressions. For a range query, it resolves to -the step width of the range query. For an instant query, it resolves to `0s`. - -`range()` can be used in duration expressions. For a range query, it resolves to -the full range of the query (end time minus start time). For an instant query, -it resolves to `0s`. This is particularly useful in combination with `@ end()` -to look back over the entire query range, e.g., -`max_over_time(metric[range()] @ end())`. - -`min(, )` and `max(, )` can be used to -find the minimum or maximum of two duration expressions. - -Duration expressions are not supported in the @ timestamp operator. - -The following operators are supported: - -* `+` - addition. -* `-` - subtraction. -* `*` - multiplication. -* `/` - division. -* `%` - modulo. -* `^` - exponentiation. - -Examples of equivalent durations: - -* `5m * 2` is equivalent to `10m` or `600s`. -* `10m - 1m` is equivalent to `9m` or `540s`. -* `(5 + 2) * 1m` is equivalent to `7m` or `420s`. -* `1h / 2` is equivalent to `30m` or `1800s`. -* `4h % 3h` is equivalent to `1h` or `3600s`. -* `(2 ^ 3) * 1m` is equivalent to `8m` or `480s`. -* `step() + 1` is equivalent to the query step width increased by 1s. -* `max(step(), 5s)` is equivalent to the larger of the query step width and `5s`. -* `min(2 * step() + 5s, 5m)` is equivalent to the smaller of twice the query step increased by `5s` and `5m`. - ## Time series selectors These are the basic building-blocks that instruct PromQL what data to fetch. @@ -333,13 +282,14 @@ A workaround for this restriction is to use the `__name__` label: Range vector literals work like instant vector literals, except that they select a range of samples back from the current instant. Syntactically, a -[duration](#float-literals-and-time-durations) is appended in square brackets -(`[]`) at the end of a vector selector to specify how far back in time values -should be fetched for each resulting range vector element. Commonly, this uses -one or more time units, e.g. `[5m]`. The range is a left-open and right-closed -interval, i.e. samples with timestamps coinciding with the left boundary of the -range are excluded from the selection, while samples coinciding with the right -boundary of the range are included in the selection. +[float literal](#float-literals-and-time-durations) is appended in square +brackets (`[]`) at the end of a vector selector to specify for how many seconds +back in time values should be fetched for each resulting range vector element. +Commonly, the float literal uses the syntax with one or more time units, e.g. +`[5m]`. The range is a left-open and right-closed interval, i.e. samples with +timestamps coinciding with the left boundary of the range are excluded from the +selection, while samples coinciding with the right boundary of the range are +included in the selection. In this example, we select all the values recorded less than 5m ago for all time series that have the metric name `http_requests_total` and a `job` label @@ -429,9 +379,8 @@ Note that the `@` modifier allows a query to look ahead of its evaluation time. Subquery allows you to run an instant query for a given range and resolution. The result of a subquery is a range vector. -Syntax: ` '[' ':' [] ']' [ @ ] [ offset ]` +Syntax: ` '[' ':' [] ']' [ @ ] [ offset ]` -* ``, ``, and `offset` support duration expressions. * `` is optional. Default is the global evaluation interval. ## Operators diff --git a/docs/querying/functions.md b/docs/querying/functions.md index 6418c2955f..a175064b81 100644 --- a/docs/querying/functions.md +++ b/docs/querying/functions.md @@ -961,7 +961,8 @@ These functions act on histograms in the following way: select the first sample of `m` _within_ the 1m range, where `m offset 1m` will select the most recent sample within the lookback interval _outside and prior to_ the 1m offset. This is particularly useful with `first_over_time(m[step()])` -in range queries to ensure that the sample selected is within the range step. +in range queries (available when `--enable-feature=promql-duration-expr` is set) +to ensure that the sample selected is within the range step. ## Trigonometric Functions diff --git a/promql/durations_test.go b/promql/durations_test.go index 3b31e92dd6..b8225ca8fc 100644 --- a/promql/durations_test.go +++ b/promql/durations_test.go @@ -23,7 +23,7 @@ import ( ) func TestDurationVisitor(t *testing.T) { - p := parser.NewParser(parser.Options{}) + p := parser.NewParser(parser.Options{ExperimentalDurationExpr: true}) complexExpr := `sum_over_time( rate(metric[5m] offset 1h)[10m:30s] offset 2h ) + diff --git a/promql/parser/features.go b/promql/parser/features.go index d21c7470e6..3bd3c493f5 100644 --- a/promql/parser/features.go +++ b/promql/parser/features.go @@ -53,6 +53,6 @@ func (pql *promQLParser) RegisterFeatures(r features.Collector) { r.Set(features.PromQLFunctions, f, !fc.Experimental || pql.options.EnableExperimentalFunctions) } - // Register parser features. - r.Enable(features.PromQL, "duration_expr") + // Register experimental parser features. + r.Set(features.PromQL, "duration_expr", pql.options.ExperimentalDurationExpr) } diff --git a/promql/parser/generated_parser.y b/promql/parser/generated_parser.y index c1524f5669..39dfa1f49f 100644 --- a/promql/parser/generated_parser.y +++ b/promql/parser/generated_parser.y @@ -1327,18 +1327,22 @@ duration_expr : number_duration_literal } | duration_expr ADD duration_expr { + yylex.(*parser).experimentalDurationExpr($1.(Expr)) $$ = &DurationExpr{Op: ADD, LHS: $1.(Expr), RHS: $3.(Expr)} } | duration_expr SUB duration_expr { + yylex.(*parser).experimentalDurationExpr($1.(Expr)) $$ = &DurationExpr{Op: SUB, LHS: $1.(Expr), RHS: $3.(Expr)} } | duration_expr MUL duration_expr { + yylex.(*parser).experimentalDurationExpr($1.(Expr)) $$ = &DurationExpr{Op: MUL, LHS: $1.(Expr), RHS: $3.(Expr)} } | duration_expr DIV duration_expr { + yylex.(*parser).experimentalDurationExpr($1.(Expr)) if nl, ok := $3.(*NumberLiteral); ok && nl.Val == 0 { yylex.(*parser).addParseErrf($2.PositionRange(), "division by zero") $$ = &NumberLiteral{Val: 0} @@ -1348,6 +1352,7 @@ duration_expr : number_duration_literal } | duration_expr MOD duration_expr { + yylex.(*parser).experimentalDurationExpr($1.(Expr)) if nl, ok := $3.(*NumberLiteral); ok && nl.Val == 0 { yylex.(*parser).addParseErrf($2.PositionRange(), "modulo by zero") $$ = &NumberLiteral{Val: 0} @@ -1357,6 +1362,7 @@ duration_expr : number_duration_literal } | duration_expr POW duration_expr { + yylex.(*parser).experimentalDurationExpr($1.(Expr)) $$ = &DurationExpr{Op: POW, LHS: $1.(Expr), RHS: $3.(Expr)} } | STEP LEFT_PAREN RIGHT_PAREN @@ -1390,6 +1396,7 @@ duration_expr : number_duration_literal paren_duration_expr : LEFT_PAREN duration_expr RIGHT_PAREN { + yylex.(*parser).experimentalDurationExpr($2.(Expr)) if durationExpr, ok := $2.(*DurationExpr); ok { durationExpr.Wrapped = true $$ = durationExpr diff --git a/promql/parser/generated_parser.y.go b/promql/parser/generated_parser.y.go index db7c239b55..bf96f73f5a 100644 --- a/promql/parser/generated_parser.y.go +++ b/promql/parser/generated_parser.y.go @@ -2446,21 +2446,25 @@ yydefault: case 294: yyDollar = yyS[yypt-3 : yypt+1] { + yylex.(*parser).experimentalDurationExpr(yyDollar[1].node.(Expr)) yyVAL.node = &DurationExpr{Op: ADD, LHS: yyDollar[1].node.(Expr), RHS: yyDollar[3].node.(Expr)} } case 295: yyDollar = yyS[yypt-3 : yypt+1] { + yylex.(*parser).experimentalDurationExpr(yyDollar[1].node.(Expr)) yyVAL.node = &DurationExpr{Op: SUB, LHS: yyDollar[1].node.(Expr), RHS: yyDollar[3].node.(Expr)} } case 296: yyDollar = yyS[yypt-3 : yypt+1] { + yylex.(*parser).experimentalDurationExpr(yyDollar[1].node.(Expr)) yyVAL.node = &DurationExpr{Op: MUL, LHS: yyDollar[1].node.(Expr), RHS: yyDollar[3].node.(Expr)} } case 297: yyDollar = yyS[yypt-3 : yypt+1] { + yylex.(*parser).experimentalDurationExpr(yyDollar[1].node.(Expr)) if nl, ok := yyDollar[3].node.(*NumberLiteral); ok && nl.Val == 0 { yylex.(*parser).addParseErrf(yyDollar[2].item.PositionRange(), "division by zero") yyVAL.node = &NumberLiteral{Val: 0} @@ -2471,6 +2475,7 @@ yydefault: case 298: yyDollar = yyS[yypt-3 : yypt+1] { + yylex.(*parser).experimentalDurationExpr(yyDollar[1].node.(Expr)) if nl, ok := yyDollar[3].node.(*NumberLiteral); ok && nl.Val == 0 { yylex.(*parser).addParseErrf(yyDollar[2].item.PositionRange(), "modulo by zero") yyVAL.node = &NumberLiteral{Val: 0} @@ -2481,6 +2486,7 @@ yydefault: case 299: yyDollar = yyS[yypt-3 : yypt+1] { + yylex.(*parser).experimentalDurationExpr(yyDollar[1].node.(Expr)) yyVAL.node = &DurationExpr{Op: POW, LHS: yyDollar[1].node.(Expr), RHS: yyDollar[3].node.(Expr)} } case 300: @@ -2515,6 +2521,7 @@ yydefault: case 304: yyDollar = yyS[yypt-3 : yypt+1] { + yylex.(*parser).experimentalDurationExpr(yyDollar[2].node.(Expr)) if durationExpr, ok := yyDollar[2].node.(*DurationExpr); ok { durationExpr.Wrapped = true yyVAL.node = durationExpr diff --git a/promql/parser/parse.go b/promql/parser/parse.go index 8d4491ea64..ec3e1001d9 100644 --- a/promql/parser/parse.go +++ b/promql/parser/parse.go @@ -43,6 +43,7 @@ var parserPool = sync.Pool{ // Options holds the configuration for the PromQL parser. type Options struct { EnableExperimentalFunctions bool + ExperimentalDurationExpr bool EnableExtendedRangeSelectors bool EnableBinopFillModifiers bool } @@ -1192,6 +1193,12 @@ func (p *parser) getAtModifierVars(e Node) (**int64, *ItemType, *posrange.Pos, b return timestampp, preprocp, endPosp, true } +func (p *parser) experimentalDurationExpr(e Expr) { + if !p.options.ExperimentalDurationExpr { + p.addParseErrf(e.PositionRange(), "experimental duration expression is not enabled") + } +} + func MustLabelMatcher(mt labels.MatchType, name, val string) *labels.Matcher { m, err := labels.NewMatcher(mt, name, val) if err != nil { diff --git a/promql/parser/parse_test.go b/promql/parser/parse_test.go index b3ea1bb0f4..6a6c50ee23 100644 --- a/promql/parser/parse_test.go +++ b/promql/parser/parse_test.go @@ -5327,6 +5327,7 @@ func readable(s string) string { func TestParseExpressions(t *testing.T) { optsParser := NewParser(Options{ EnableExperimentalFunctions: true, + ExperimentalDurationExpr: true, }) for _, test := range testExpr { @@ -6083,6 +6084,7 @@ func TestParseCustomFunctions(t *testing.T) { func TestNewParser(t *testing.T) { p := NewParser(Options{ EnableExperimentalFunctions: true, + ExperimentalDurationExpr: true, }) // ParseExpr should work. diff --git a/promql/parser/prettier_test.go b/promql/parser/prettier_test.go index 47e5407e30..d00bc283ec 100644 --- a/promql/parser/prettier_test.go +++ b/promql/parser/prettier_test.go @@ -670,7 +670,7 @@ func TestUnaryPretty(t *testing.T) { } func TestDurationExprPretty(t *testing.T) { - optsParser := NewParser(Options{}) + optsParser := NewParser(Options{ExperimentalDurationExpr: true}) maxCharactersPerLine = 10 inputs := []struct { in, out string diff --git a/promql/parser/printer_test.go b/promql/parser/printer_test.go index 774ff77d2f..eae91d4f88 100644 --- a/promql/parser/printer_test.go +++ b/promql/parser/printer_test.go @@ -23,6 +23,7 @@ import ( func TestExprString(t *testing.T) { optsParser := NewParser(Options{ + ExperimentalDurationExpr: true, EnableExtendedRangeSelectors: true, EnableBinopFillModifiers: true, }) diff --git a/promql/promqltest/test.go b/promql/promqltest/test.go index 0be88829bf..85c0c4f88a 100644 --- a/promql/promqltest/test.go +++ b/promql/promqltest/test.go @@ -90,6 +90,7 @@ func LoadedStorage(t testing.TB, input string) *teststorage.TestStorage { // TestParserOpts are the parser options used for all built-in test engines. var TestParserOpts = parser.Options{ EnableExperimentalFunctions: true, + ExperimentalDurationExpr: true, EnableExtendedRangeSelectors: true, EnableBinopFillModifiers: true, } diff --git a/util/fuzzing/fuzz_test.go b/util/fuzzing/fuzz_test.go index 32353c6afc..747eab1f1a 100644 --- a/util/fuzzing/fuzz_test.go +++ b/util/fuzzing/fuzz_test.go @@ -363,6 +363,7 @@ func FuzzParseExpr(f *testing.F) { p := parser.NewParser(parser.Options{ EnableExperimentalFunctions: true, + ExperimentalDurationExpr: true, EnableExtendedRangeSelectors: true, EnableBinopFillModifiers: true, }) diff --git a/web/ui/mantine-ui/src/promql/functionDocs.tsx b/web/ui/mantine-ui/src/promql/functionDocs.tsx index 375c4155d4..7ea47c02bb 100644 --- a/web/ui/mantine-ui/src/promql/functionDocs.tsx +++ b/web/ui/mantine-ui/src/promql/functionDocs.tsx @@ -589,7 +589,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -908,7 +909,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -1238,7 +1240,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -2069,7 +2072,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -2219,7 +2223,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -2328,7 +2333,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -2437,7 +2443,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -2652,7 +2659,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -2761,7 +2769,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -3274,7 +3283,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -3383,7 +3393,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -3508,7 +3519,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -3773,7 +3785,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -3882,7 +3895,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -3991,7 +4005,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), @@ -4100,7 +4115,8 @@ const funcDocs: Record = { first sample of m within the 1m range, where m offset 1m will select the most recent sample within the lookback interval outside and prior to the 1m offset. This is particularly useful with first_over_time(m[step()]) - in range queries to ensure that the sample selected is within the range step. + in range queries (available when --enable-feature=promql-duration-expr is set) to ensure that the + sample selected is within the range step.

), From 502e31a82fe42ec56de76f658c303b1ab7a91a00 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 13 May 2026 09:56:54 +0200 Subject: [PATCH 047/170] promql: protect min(), max(), step(), and range() duration exprs with feature flag min(), max(), step(), and range() in duration expression context were not guarded by the ExperimentalDurationExpr feature flag, unlike the binary operators (+, -, *, /, %, ^). Add the missing experimentalDurationExpr() calls in both offset_duration_expr and duration_expr grammar rules. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- promql/parser/generated_parser.y | 44 ++++++++++++++++++++--------- promql/parser/generated_parser.y.go | 36 +++++++++++++++++------ 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/promql/parser/generated_parser.y b/promql/parser/generated_parser.y index 39dfa1f49f..34ce028c1f 100644 --- a/promql/parser/generated_parser.y +++ b/promql/parser/generated_parser.y @@ -1201,23 +1201,27 @@ offset_duration_expr : number_duration_literal } | STEP LEFT_PAREN RIGHT_PAREN { - $$ = &DurationExpr{ - Op: STEP, + de := &DurationExpr{ + Op: STEP, StartPos: $1.PositionRange().Start, - EndPos: $3.PositionRange().End, + EndPos: $3.PositionRange().End, } + yylex.(*parser).experimentalDurationExpr(de) + $$ = de } | RANGE LEFT_PAREN RIGHT_PAREN { - $$ = &DurationExpr{ - Op: RANGE, + de := &DurationExpr{ + Op: RANGE, StartPos: $1.PositionRange().Start, - EndPos: $3.PositionRange().End, + EndPos: $3.PositionRange().End, } + yylex.(*parser).experimentalDurationExpr(de) + $$ = de } | unary_op STEP LEFT_PAREN RIGHT_PAREN { - $$ = &DurationExpr{ + de := &DurationExpr{ Op: $1.Typ, RHS: &DurationExpr{ Op: STEP, @@ -1226,10 +1230,12 @@ offset_duration_expr : number_duration_literal }, StartPos: $1.Pos, } + yylex.(*parser).experimentalDurationExpr(de) + $$ = de } | unary_op RANGE LEFT_PAREN RIGHT_PAREN { - $$ = &DurationExpr{ + de := &DurationExpr{ Op: $1.Typ, RHS: &DurationExpr{ Op: RANGE, @@ -1238,20 +1244,24 @@ offset_duration_expr : number_duration_literal }, StartPos: $1.Pos, } + yylex.(*parser).experimentalDurationExpr(de) + $$ = de } | min_max LEFT_PAREN duration_expr COMMA duration_expr RIGHT_PAREN { - $$ = &DurationExpr{ + de := &DurationExpr{ Op: $1.Typ, StartPos: $1.PositionRange().Start, EndPos: $6.PositionRange().End, LHS: $3.(Expr), RHS: $5.(Expr), } + yylex.(*parser).experimentalDurationExpr(de) + $$ = de } | unary_op min_max LEFT_PAREN duration_expr COMMA duration_expr RIGHT_PAREN { - $$ = &DurationExpr{ + de := &DurationExpr{ Op: $1.Typ, StartPos: $1.Pos, EndPos: $6.PositionRange().End, @@ -1263,6 +1273,8 @@ offset_duration_expr : number_duration_literal RHS: $6.(Expr), }, } + yylex.(*parser).experimentalDurationExpr(de) + $$ = de } | unary_op LEFT_PAREN duration_expr RIGHT_PAREN %prec MUL { @@ -1367,29 +1379,35 @@ duration_expr : number_duration_literal } | STEP LEFT_PAREN RIGHT_PAREN { - $$ = &DurationExpr{ + de := &DurationExpr{ Op: STEP, StartPos: $1.PositionRange().Start, EndPos: $3.PositionRange().End, } + yylex.(*parser).experimentalDurationExpr(de) + $$ = de } | RANGE LEFT_PAREN RIGHT_PAREN { - $$ = &DurationExpr{ + de := &DurationExpr{ Op: RANGE, StartPos: $1.PositionRange().Start, EndPos: $3.PositionRange().End, } + yylex.(*parser).experimentalDurationExpr(de) + $$ = de } | min_max LEFT_PAREN duration_expr COMMA duration_expr RIGHT_PAREN { - $$ = &DurationExpr{ + de := &DurationExpr{ Op: $1.Typ, StartPos: $1.PositionRange().Start, EndPos: $6.PositionRange().End, LHS: $3.(Expr), RHS: $5.(Expr), } + yylex.(*parser).experimentalDurationExpr(de) + $$ = de } | paren_duration_expr ; diff --git a/promql/parser/generated_parser.y.go b/promql/parser/generated_parser.y.go index bf96f73f5a..9f9f017dfa 100644 --- a/promql/parser/generated_parser.y.go +++ b/promql/parser/generated_parser.y.go @@ -2316,25 +2316,29 @@ yydefault: case 282: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.node = &DurationExpr{ + de := &DurationExpr{ Op: STEP, StartPos: yyDollar[1].item.PositionRange().Start, EndPos: yyDollar[3].item.PositionRange().End, } + yylex.(*parser).experimentalDurationExpr(de) + yyVAL.node = de } case 283: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.node = &DurationExpr{ + de := &DurationExpr{ Op: RANGE, StartPos: yyDollar[1].item.PositionRange().Start, EndPos: yyDollar[3].item.PositionRange().End, } + yylex.(*parser).experimentalDurationExpr(de) + yyVAL.node = de } case 284: yyDollar = yyS[yypt-4 : yypt+1] { - yyVAL.node = &DurationExpr{ + de := &DurationExpr{ Op: yyDollar[1].item.Typ, RHS: &DurationExpr{ Op: STEP, @@ -2343,11 +2347,13 @@ yydefault: }, StartPos: yyDollar[1].item.Pos, } + yylex.(*parser).experimentalDurationExpr(de) + yyVAL.node = de } case 285: yyDollar = yyS[yypt-4 : yypt+1] { - yyVAL.node = &DurationExpr{ + de := &DurationExpr{ Op: yyDollar[1].item.Typ, RHS: &DurationExpr{ Op: RANGE, @@ -2356,22 +2362,26 @@ yydefault: }, StartPos: yyDollar[1].item.Pos, } + yylex.(*parser).experimentalDurationExpr(de) + yyVAL.node = de } case 286: yyDollar = yyS[yypt-6 : yypt+1] { - yyVAL.node = &DurationExpr{ + de := &DurationExpr{ Op: yyDollar[1].item.Typ, StartPos: yyDollar[1].item.PositionRange().Start, EndPos: yyDollar[6].item.PositionRange().End, LHS: yyDollar[3].node.(Expr), RHS: yyDollar[5].node.(Expr), } + yylex.(*parser).experimentalDurationExpr(de) + yyVAL.node = de } case 287: yyDollar = yyS[yypt-7 : yypt+1] { - yyVAL.node = &DurationExpr{ + de := &DurationExpr{ Op: yyDollar[1].item.Typ, StartPos: yyDollar[1].item.Pos, EndPos: yyDollar[6].node.PositionRange().End, @@ -2383,6 +2393,8 @@ yydefault: RHS: yyDollar[6].node.(Expr), }, } + yylex.(*parser).experimentalDurationExpr(de) + yyVAL.node = de } case 288: yyDollar = yyS[yypt-4 : yypt+1] @@ -2492,31 +2504,37 @@ yydefault: case 300: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.node = &DurationExpr{ + de := &DurationExpr{ Op: STEP, StartPos: yyDollar[1].item.PositionRange().Start, EndPos: yyDollar[3].item.PositionRange().End, } + yylex.(*parser).experimentalDurationExpr(de) + yyVAL.node = de } case 301: yyDollar = yyS[yypt-3 : yypt+1] { - yyVAL.node = &DurationExpr{ + de := &DurationExpr{ Op: RANGE, StartPos: yyDollar[1].item.PositionRange().Start, EndPos: yyDollar[3].item.PositionRange().End, } + yylex.(*parser).experimentalDurationExpr(de) + yyVAL.node = de } case 302: yyDollar = yyS[yypt-6 : yypt+1] { - yyVAL.node = &DurationExpr{ + de := &DurationExpr{ Op: yyDollar[1].item.Typ, StartPos: yyDollar[1].item.PositionRange().Start, EndPos: yyDollar[6].item.PositionRange().End, LHS: yyDollar[3].node.(Expr), RHS: yyDollar[5].node.(Expr), } + yylex.(*parser).experimentalDurationExpr(de) + yyVAL.node = de } case 304: yyDollar = yyS[yypt-3 : yypt+1] From dd406b3df5002cf67a298b73928ec7435024102f Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 13 May 2026 10:52:59 +0200 Subject: [PATCH 048/170] web/api/v1: enable ExperimentalDurationExpr in translate AST tests Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- web/api/v1/translate_ast_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/api/v1/translate_ast_test.go b/web/api/v1/translate_ast_test.go index 50befb1962..84c4019363 100644 --- a/web/api/v1/translate_ast_test.go +++ b/web/api/v1/translate_ast_test.go @@ -22,7 +22,7 @@ import ( ) func TestTranslateASTDurationExpressions(t *testing.T) { - p := parser.NewParser(parser.Options{}) + p := parser.NewParser(parser.Options{ExperimentalDurationExpr: true}) type tc struct { name string From 20946d5e1d54980f87747687fda59975fd4d6733 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 13 May 2026 17:00:10 +0200 Subject: [PATCH 049/170] Improve warnings handling Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- promql/functions.go | 70 +++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/promql/functions.go b/promql/functions.go index e5608c37c4..31ff6a4093 100644 --- a/promql/functions.go +++ b/promql/functions.go @@ -228,6 +228,45 @@ func subHistogramWithAnnotations(base, other *histogram.FloatHistogram, annos *a return true } +// validateHistogramRange checks all histogram samples in h for schema +// consistency and counter-type hints. It returns false (and adds an annotation +// to annos) when exponential and custom buckets are mixed. It adds a +// NativeHistogramNotCounterWarning for any sample carrying a gauge hint while +// isCounter is true. +func validateHistogramRange(h []HPoint, isCounter bool, annos *annotations.Annotations, metricName string, pos posrange.PositionRange) bool { + usingCustomBuckets := h[0].H.UsesCustomBuckets() + for _, p := range h { + if p.H.UsesCustomBuckets() != usingCustomBuckets { + annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(metricName, pos)) + return false + } + if isCounter && p.H.CounterResetHint == histogram.GaugeType { + annos.Add(annotations.NewNativeHistogramNotCounterWarning(metricName, pos)) + } + } + return true +} + +// innerHistogramBounds returns the (first, last) indices for the inner slice +// passed to correctForCounterResetsHistogram. firstSampleIndex is always +// excluded because it is already represented by left (directly or via +// interpolation). When the left-boundary interpolation itself spanned a reset +// (smoothed mode, first sample before rangeStart, DetectReset true), the reset +// between firstSampleIndex and firstSampleIndex+1 is already accounted for, so +// firstSampleIndex+1 is also excluded. lastSampleIndex is excluded when its +// timestamp is at or after rangeEnd, mirroring the float version. +func innerHistogramBounds(h []HPoint, firstSampleIndex, lastSampleIndex int, rangeStart, rangeEnd int64, smoothed bool) (int, int) { + first := firstSampleIndex + 1 + if smoothed && h[firstSampleIndex].T < rangeStart && h[firstSampleIndex+1].H.DetectReset(h[firstSampleIndex].H) { + first++ + } + last := lastSampleIndex + if h[last].T >= rangeEnd { + last-- + } + return first, last +} + // correctForCounterResetsHistogram calculates the histogram correction for // counter resets in points, using left and right as the boundary samples. // It is only used by extendedHistogramRate. It returns the accumulated @@ -349,14 +388,8 @@ func extendedHistogramRate(vals Matrix, args parser.Expressions, enh *EvalNodeHe return enh.Out, annos } - usingCustomBuckets := h[firstSampleIndex].H.UsesCustomBuckets() - for _, p := range h[firstSampleIndex : lastSampleIndex+1] { - if p.H.UsesCustomBuckets() != usingCustomBuckets { - return enh.Out, annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(metricName, pos)) - } - if isCounter && p.H.CounterResetHint == histogram.GaugeType { - annos.Add(annotations.NewNativeHistogramNotCounterWarning(metricName, pos)) - } + if !validateHistogramRange(h[firstSampleIndex:lastSampleIndex+1], isCounter, &annos, metricName, pos) { + return enh.Out, annos } left, err := pickOrInterpolateLeftHistogram(h, firstSampleIndex, rangeStart, smoothed, isCounter, &annos, pos) @@ -372,32 +405,13 @@ func extendedHistogramRate(vals Matrix, args parser.Expressions, enh *EvalNodeHe annos.Add(annotations.NewNativeHistogramNotGaugeWarning(metricName, pos)) } - // Compute result = right - left. resultHistogram := right.Copy() if !subHistogramWithAnnotations(resultHistogram, left, &annos, metricName, pos) { return enh.Out, annos } if isCounter { - leftInterpolationHandledReset := smoothed && h[firstSampleIndex].T < rangeStart && h[firstSampleIndex+1].H.DetectReset(h[firstSampleIndex].H) - - // Always skip firstSampleIndex: it is either already represented by - // left (when h[firstSampleIndex].T >= rangeStart) or by the - // interpolation between h[firstSampleIndex] and h[firstSampleIndex+1] - // (when smoothed). Including it in the correction slice would - // double-count via DetectReset's CounterReset shortcut when - // h[firstSampleIndex].CounterResetHint == CounterReset. - first := firstSampleIndex + 1 - if leftInterpolationHandledReset { - // The reset between h[firstSampleIndex] and h[firstSampleIndex+1] - // is already accounted for by the left boundary interpolation. - first++ - } - last := lastSampleIndex - if h[last].T >= rangeEnd { - last-- - } - + first, last := innerHistogramBounds(h, firstSampleIndex, lastSampleIndex, rangeStart, rangeEnd, smoothed) if first <= last { correction, newAnnos, ok := correctForCounterResetsHistogram(left, right, h[first:last+1], metricName, pos) annos.Merge(newAnnos) From 76c859969d85d1ed03990283f61686535bd08f34 Mon Sep 17 00:00:00 2001 From: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> Date: Wed, 13 May 2026 17:35:52 +0200 Subject: [PATCH 050/170] promql: rename min/max duration expr functions to least/greatest Rename the `min()` and `max()` duration expression functions to `least()` and `greatest()` to avoid conflicts with the existing PromQL aggregate functions `min` and `max`. Update documentation and tests accordingly. Signed-off-by: Julien Pivotto <291750+roidelapluie@users.noreply.github.com> --- docs/feature_flags.md | 9 +- promql/durations.go | 4 +- promql/durations_test.go | 4 +- promql/parser/generated_parser.y | 16 +- promql/parser/generated_parser.y.go | 1072 +++++++++-------- promql/parser/lex.go | 18 +- promql/parser/parse_test.go | 60 +- promql/parser/printer.go | 8 +- promql/parser/printer_test.go | 18 +- .../testdata/duration_expression.test | 26 +- web/api/v1/translate_ast_test.go | 16 +- 11 files changed, 638 insertions(+), 613 deletions(-) diff --git a/docs/feature_flags.md b/docs/feature_flags.md index 2806e4baa7..5bee9814d3 100644 --- a/docs/feature_flags.md +++ b/docs/feature_flags.md @@ -223,7 +223,10 @@ For a **range query**, it resolves to the full range of the query (end time - st For an **instant query**, it resolves to `0s`. This is particularly useful in combination with `@end()` to look back over the entire query range, e.g., `max_over_time(metric[range()] @ end())`. -`min(, )` and `max(, )` can be used to find the minimum or maximum of two duration expressions. +`least(, )` and `greatest(, )` select between two duration expressions. +`least` returns the smaller of the two, which is useful for capping a duration at a maximum value. +`greatest` returns the larger of the two, which is useful for enforcing a minimum value. +For example, `greatest(step(), 5s)` ensures the duration is never shorter than `5s`, while `least(range(), 1h)` caps the duration at `1h`. **Note**: Duration expressions are not supported in the @ timestamp operator. @@ -245,8 +248,8 @@ Examples of equivalent durations: * `4h % 3h` is equivalent to `1h` or `3600s` * `(2 ^ 3) * 1m` is equivalent to `8m` or `480s` * `step() + 1` is equivalent to the query step width increased by 1s. -* `max(step(), 5s)` is equivalent to the larger of the query step width and `5s`. -* `min(2 * step() + 5s, 5m)` is equivalent to the smaller of twice the query step increased by `5s` and `5m`. +* `greatest(step(), 5s)` is equivalent to the larger of the query step width and `5s`. +* `least(2 * step() + 5s, 5m)` is equivalent to the smaller of twice the query step increased by `5s` and `5m`. ## OTLP Native Delta Support diff --git a/promql/durations.go b/promql/durations.go index 3dc44fbbc6..94099888c0 100644 --- a/promql/durations.go +++ b/promql/durations.go @@ -135,9 +135,9 @@ func (v *durationVisitor) evaluateDurationExpr(expr parser.Expr) (float64, error return float64(v.step.Seconds()), nil case parser.RANGE: return float64(v.queryRange.Seconds()), nil - case parser.MIN: + case parser.LEAST: return math.Min(lhs, rhs), nil - case parser.MAX: + case parser.GREATEST: return math.Max(lhs, rhs), nil case parser.ADD: if n.LHS == nil { diff --git a/promql/durations_test.go b/promql/durations_test.go index b8225ca8fc..d11ec3885a 100644 --- a/promql/durations_test.go +++ b/promql/durations_test.go @@ -228,7 +228,7 @@ func TestCalculateDuration(t *testing.T) { expected: 150 * time.Second, }, { - name: "max of step and range", + name: "greatest of step and range", expr: &parser.DurationExpr{ LHS: &parser.DurationExpr{ Op: parser.STEP, @@ -236,7 +236,7 @@ func TestCalculateDuration(t *testing.T) { RHS: &parser.DurationExpr{ Op: parser.RANGE, }, - Op: parser.MAX, + Op: parser.GREATEST, }, expected: 5 * time.Minute, }, diff --git a/promql/parser/generated_parser.y b/promql/parser/generated_parser.y index 34ce028c1f..2ad96b53c9 100644 --- a/promql/parser/generated_parser.y +++ b/promql/parser/generated_parser.y @@ -159,6 +159,8 @@ START END STEP RANGE +GREATEST +LEAST %token preprocessorEnd // Counter reset hints. @@ -183,7 +185,7 @@ START_METRIC_SELECTOR // Type definitions for grammar rules. %type label_match_list %type label_matcher -%type aggregate_op grouping_label match_op maybe_label metric_identifier unary_op at_modifier_preprocessors string_identifier counter_reset_hint min_max +%type aggregate_op grouping_label match_op maybe_label metric_identifier unary_op at_modifier_preprocessors string_identifier counter_reset_hint greatest_least %type label_set metric %type label_set_list %type