mirror of
https://github.com/prometheus/prometheus.git
synced 2026-06-20 13:59:23 -04:00
Merge remote-tracking branch 'upstream/main' into improve-config-coverage
Signed-off-by: LorenzoDOrtona <dortonalorenzo@gmail.com> # Conflicts: # config/config_test.go
This commit is contained in:
commit
052d8c2d84
204 changed files with 16408 additions and 3057 deletions
2
.github/workflows/check_release_notes.yml
vendored
2
.github/workflows/check_release_notes.yml
vendored
|
|
@ -20,6 +20,8 @@ jobs:
|
|||
if: (github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community') && github.event.pull_request.user.login != 'dependabot[bot]'
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- env:
|
||||
PR_DESCRIPTION: ${{ github.event.pull_request.body }}
|
||||
run: |
|
||||
|
|
|
|||
51
.github/workflows/ci.yml
vendored
51
.github/workflows/ci.yml
vendored
|
|
@ -42,11 +42,25 @@ jobs:
|
|||
- run: go test --tags=dedupelabels ./...
|
||||
- run: go test --tags=slicelabels -race ./cmd/prometheus ./model/textparse ./prompb/...
|
||||
- run: go test --tags=forcedirectio -race ./tsdb/
|
||||
- run: GOARCH=386 go test ./...
|
||||
- run: make protoc
|
||||
- run: make proto
|
||||
- run: git diff --exit-code
|
||||
|
||||
test_go_386:
|
||||
name: Go tests for 32-bit x86
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: quay.io/prometheus/golang-builder:1.26-base
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: prometheus/promci-setup@5af30ba8c199a91d6c04ebdc3c48e630e355f62d # v0.1.0
|
||||
# NOTE(bwplotka): We limit concurrency to avoid issues around too many concurrent mmaps
|
||||
# caused by parallel tests. See context: https://github.com/prometheus/prometheus/pull/18709
|
||||
# Alternatively we could adjust each relevant test to have 386 aware parallelization setting.
|
||||
- run: GOARCH=386 go test -parallel=1 ./...
|
||||
|
||||
test_version_upgrade:
|
||||
name: Go tests for Prometheus upgrades and downgrades
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -140,7 +154,7 @@ jobs:
|
|||
container:
|
||||
# Whenever the Go version is updated here, .promu.yml
|
||||
# should also be updated.
|
||||
image: quay.io/prometheus/golang-builder:1.25-base
|
||||
image: quay.io/prometheus/golang-builder:1.26-base
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
|
|
@ -167,10 +181,7 @@ jobs:
|
|||
matrix:
|
||||
thread: [ 0, 1, 2 ]
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: prometheus/promci/build@769ee18070cd21cfc2a24fa912349fd3e48dee58 # v0.6.0
|
||||
- uses: prometheus/promci/build@d9d4f5688814f0b77bf003d07fb8c00507390634 # v0.8.2
|
||||
with:
|
||||
promu_opts: "-p linux/amd64 -p windows/amd64 -p linux/arm64 -p darwin/amd64 -p darwin/arm64 -p linux/386"
|
||||
parallelism: 3
|
||||
|
|
@ -193,10 +204,7 @@ jobs:
|
|||
# Whenever the Go version is updated here, .promu.yml
|
||||
# should also be updated.
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: prometheus/promci/build@769ee18070cd21cfc2a24fa912349fd3e48dee58 # v0.6.0
|
||||
- uses: prometheus/promci/build@d9d4f5688814f0b77bf003d07fb8c00507390634 # v0.8.2
|
||||
with:
|
||||
parallelism: 12
|
||||
thread: ${{ matrix.thread }}
|
||||
|
|
@ -296,37 +304,38 @@ jobs:
|
|||
publish_main:
|
||||
name: Publish main branch artifacts
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
packages: write
|
||||
needs: [test_ui, test_go, test_go_more, test_go_oldest, test_windows, golangci, codeql, build_all]
|
||||
if: github.event_name == 'push' && github.event.ref == 'refs/heads/main'
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: prometheus/promci/publish_main@769ee18070cd21cfc2a24fa912349fd3e48dee58 # v0.6.0
|
||||
- uses: prometheus/promci/publish_main@d9d4f5688814f0b77bf003d07fb8c00507390634 # v0.8.2
|
||||
with:
|
||||
docker_hub_login: ${{ secrets.docker_hub_login }}
|
||||
docker_hub_password: ${{ secrets.docker_hub_password }}
|
||||
ghcr_io_password: ${{ github.token }}
|
||||
quay_io_login: ${{ secrets.quay_io_login }}
|
||||
quay_io_password: ${{ secrets.quay_io_password }}
|
||||
publish_release:
|
||||
name: Publish release artefacts
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
packages: write
|
||||
needs: [test_ui, test_go, test_go_more, test_go_oldest, test_windows, golangci, codeql, build_all]
|
||||
if: |
|
||||
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v2.'))
|
||||
||
|
||||
(github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v3.'))
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: prometheus/promci/publish_release@769ee18070cd21cfc2a24fa912349fd3e48dee58 # v0.6.0
|
||||
- uses: prometheus/promci/publish_release@d9d4f5688814f0b77bf003d07fb8c00507390634 # v0.8.2
|
||||
with:
|
||||
docker_hub_login: ${{ secrets.docker_hub_login }}
|
||||
docker_hub_password: ${{ secrets.docker_hub_password }}
|
||||
ghcr_io_password: ${{ github.token }}
|
||||
quay_io_login: ${{ secrets.quay_io_login }}
|
||||
quay_io_password: ${{ secrets.quay_io_password }}
|
||||
github_token: ${{ secrets.PROMBOT_GITHUB_TOKEN }}
|
||||
github_token: ${{ github.token }}
|
||||
publish_ui_release:
|
||||
name: Publish UI on npm Registry
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -337,11 +346,11 @@ 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"
|
||||
- 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') }}
|
||||
|
|
|
|||
6
.github/workflows/codeql-analysis.yml
vendored
6
.github/workflows/codeql-analysis.yml
vendored
|
|
@ -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@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/autobuild@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
||||
uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
|
||||
|
|
|
|||
2
.github/workflows/fuzzing.yml
vendored
2
.github/workflows/fuzzing.yml
vendored
|
|
@ -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, '-') }}
|
||||
|
|
|
|||
7
.github/workflows/govulncheck.yml
vendored
7
.github/workflows/govulncheck.yml
vendored
|
|
@ -2,6 +2,9 @@
|
|||
name: govulncheck
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- VERSION
|
||||
- .github/workflows/govulncheck.yml
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
|
@ -18,4 +21,6 @@ jobs:
|
|||
name: Run govulncheck
|
||||
steps:
|
||||
- id: govulncheck
|
||||
uses: golang/govulncheck-action@31f7c5463448f83528bd771c2d978d940080c9fd # v1.0.4-unreleased
|
||||
uses: golang/govulncheck-action@b625fbe08f3bccbe446d94fbf87fcc875a4f50ee # v1.0.4
|
||||
env:
|
||||
GOOS: ${{ contains(github.repository, 'windows_exporter') && 'windows' || '' }}
|
||||
|
|
|
|||
4
.github/workflows/repo_sync.yml
vendored
4
.github/workflows/repo_sync.yml
vendored
|
|
@ -19,4 +19,6 @@ jobs:
|
|||
persist-credentials: false
|
||||
- run: ./scripts/sync_repo_files.sh
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.PROMBOT_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.PROMBOT_REPOSYNC_TOKEN }}
|
||||
GITHUB_TOKEN_PROMETHEUS: ${{ secrets.PROMBOT_REPOSYNC_TOKEN_PROMETHEUS }}
|
||||
GITHUB_TOKEN_PROMETHEUS_COMMUNITY: ${{ secrets.PROMBOT_REPOSYNC_TOKEN_PROMETHEUS_COMMUNITY }}
|
||||
|
|
|
|||
4
.github/workflows/scorecards.yml
vendored
4
.github/workflows/scorecards.yml
vendored
|
|
@ -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
|
||||
|
|
@ -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@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
|
|
|||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
|
|
@ -11,7 +11,7 @@ jobs:
|
|||
if: github.repository_owner == 'prometheus' || github.repository_owner == 'prometheus-community' # Don't run this workflow on forks.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0
|
||||
- uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# opt out of defaults to avoid marking issues as stale and closing them
|
||||
|
|
|
|||
69
CHANGELOG.md
69
CHANGELOG.md
|
|
@ -1,5 +1,74 @@
|
|||
# Changelog
|
||||
|
||||
## 3.12.0 / 2026-05-28
|
||||
|
||||
- [SECURITY] Remote-write: Reject snappy-compressed requests whose declared decoded length exceeds the 32MB. Thanks to @hibrian827 for reporting it. #18642
|
||||
- [SECURITY] STACKIT SD: Fix secrets being exposed in plaintext via `/-/config` endpoint. Thanks to @August829 and @Phaxma for reporting. GHSA-39j6-789q-qxvh #18649
|
||||
- [CHANGE] TSDB/Agent: Adds Start Timestamp field to all WAL Histogram samples in memory; used `st-storage` flag is enabled. #18221
|
||||
- [FEATURE] API: Add `/api/v1/status/self_metrics` endpoint returning the current state of the Prometheus server's own metrics about itself as JSON. #18411
|
||||
- [FEATURE] Discovery: Add DigitalOcean Managed Databases service discovery #18287
|
||||
- [FEATURE] Prometheus: Add support for the aix/ppc64 compilation target #18321
|
||||
- [FEATURE] Discovery: Add Outscale VM service discovery (`outscale_sd_configs`) for discovering scrape targets from the Outscale Cloud API. #18139
|
||||
- [FEATURE] PromQL: Emit a warning when `sort`, `sort_by_label` or `sort_by_label_desc` is used within range (matrix) queries, as these functions do not have effect in that context. #18498
|
||||
- [FEATURE] PromQL: Add `start()`, `end()`, `range()`, and `step()` experimental functions #17877
|
||||
- [FEATURE] PromQL: Update `resets()` function to consider start timestamp resets. Hidden behind `use-start-timestamps` feature flag. #18627
|
||||
- [FEATURE] Prometheus: Promote auto-reload-config as stable #18620
|
||||
- [FEATURE] TSDB/Agent: Add `CheckpointFromInMemorySeries` option to `agent.DB` that enables checkpoint based on in-memory series. #17948
|
||||
- [FEATURE] UI: Add a web interface for deleting time series and cleaning tombstones, accessible from the Status menu. #18390
|
||||
- [FEATURE] PromQL: Use start timestamps for `rate()`, `irate(), and `increase()` calculations, behind a feature flag `use-start-timestamps`. Doesn't work together with extended range selectors `anchored` and `smoothed`. #18344
|
||||
- [FEATURE] Scrape: Added a feature flag `st-synthesis` which synthesizes unknown STs for scraped cumulative metrics. Useful when Remote Writing 2.0 with delta or Otel-based backends. #18279
|
||||
- [FEATURE] promqltest: support `@st` annotation in `load` blocks to specify per-sample start timestamps. #18360
|
||||
- [ENHANCEMENT] API: reject concurrent fgprof profiles. #18651
|
||||
- [ENHANCEMENT] AWS SD: Add optional `external_id` field to ECS/MSK/RDS/Elasticache. #18579
|
||||
- [ENHANCEMENT] AWS SD: Add optional `external_id` field. #17171
|
||||
- [ENHANCEMENT] Discovery: Propagate SD target updates faster by introducing dynamic backoff interval instead of static 5s interval for throttling. #18187
|
||||
- [ENHANCEMENT] Promtool: Add `--header` flag to `query instant` command, matching existing `query range` behaviour. #18418
|
||||
- [ENHANCEMENT]: AWS SD: Allows EC2 service discovery to discover IPv6 addresses to communicate with target endpoints. The private IPv4 address remains the default when both IPv4 and IPv6 addresses are present. #16088
|
||||
- [PERF] TSDB: Make head chunk lookup in range queries constant time instead of quadratic time #18302
|
||||
- [PERF] TSDB: Skip entire stripes in mmapHeadChunks when no series need mmapping, reducing CPU utilization significantly at production-relevant scales. #18541
|
||||
- [PERF] TSDB: Skip clean series during periodic head chunk mmap using cached head chunk count #18272
|
||||
- [PERF] PromQL: Address FloatHistogram.KahanAdd performance regression on Go 1.26. #18568
|
||||
- [BUGFIX] PromQL: Fix `info()` function incorrectly handling negated `__name__` matchers #17932
|
||||
- [BUGFIX] API: Return duration expressions in `/parse_ast`. #18624
|
||||
- [BUGFIX] API: correctly document formats accepted for duration query request parameters (step, timeout and lookback delta) in OpenAPI spec #18305
|
||||
- [BUGFIX] Scrape: AppenderV2 now tracks staleness even when OOO/duplicate series errors happen similar to AppenderV1 #18567
|
||||
- [BUGFIX] Config: Validate remote_write queue_config fields at load time to prevent runtime panic and silent misconfiguration. #18209
|
||||
- [BUGFIX] Discovery/Consul: Add `health_filter` for Health API filtering, fixing breakage when using Catalog-only fields like `ServiceTags` in `filter`. #18479 #18499
|
||||
- [BUGFIX] OTLP: limit decompressed body size for gzip-encoded OTLP write requests. #18408
|
||||
- [BUGFIX] PromQL: Fix `smoothed` rate/increase returning zero instead of no result when all data falls strictly after the query range. #18523
|
||||
- [BUGFIX] PromQL: Fix metric name not being dropped when last_over_time or first_over_time is applied to subqueries containing name-dropping functions like abs(). #18409
|
||||
- [BUGFIX] PromQL: Fix missing warning when mixing exponential and custom-bucket histograms in stats queries. #18660
|
||||
- [BUGFIX] PromQL: Fix parsing of `range()` keyword in duration expressions such as `foo[5m+range()]`. #18623
|
||||
- [BUGFIX] PromQL: Fix smoothed vector selector returning no results in binary operations when the `@` modifier is used. #18531
|
||||
- [BUGFIX] PromQL: Reject NaN, infinite, and out-of-range duration expressions instead of silently producing an out-of-range time.Duration. #18639
|
||||
- [BUGFIX] Scrape: Fix panic when scraping malformed native histograms. #18414
|
||||
- [BUGFIX] Scrape: fix panic when scraping a target exposing a summary with no quantiles via the protobuf format. #18382
|
||||
- [BUGFIX] Scrape: fix scrape failure log file occasionally not applied after a configuration reload. #18421
|
||||
- [BUGFIX] TSDB: Allow retention percentage with new data path. #18628
|
||||
- [BUGFIX] TSDB: Preserve decimal precision in percentage-based retention #18374
|
||||
- [BUGFIX] TSDB: fix prometheus_tsdb_head_chunks going negative after WAL replay #18401
|
||||
- [BUGFIX] TSDB: panic with native histograms during query of overlapping chunks. #18692
|
||||
- [BUGFIX] Tracing: fix startup failure for insecure OTLP HTTP tracing #18469
|
||||
- [BUGFIX] UI: Escape label values offered by PromQL autocomplete. #18658
|
||||
- [BUGFIX] UI: Improve Y-axis tick label precision for graph values over small ranges. #18682
|
||||
- [BUGFIX] `prometheus_sd_refresh*` and `prometheus_sd_discovered_targets` metrics for specific scrape jobs are deleted when the scrape job is removed. #17614
|
||||
- [BUGFIX] Remote: fixed validation for received RW2 requests when parsing metadata unit symbols. This fixes a case when request would cause (recovered) handler panic. #18641
|
||||
- [BUGFIX] TSDB/Agent: fix race in agent appender where concurrent appends for the same label set could produce duplicate in-memory series and duplicate WAL records. #18292
|
||||
- [BUGFIX] Config: Update `--enable-feature` flag description and sort feature names. #18487
|
||||
|
||||
## 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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
3.11.2
|
||||
3.12.0
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
|
|
@ -263,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":
|
||||
|
|
@ -284,6 +282,11 @@ func (c *flagConfig) setFeatureListOptions(logger *slog.Logger) error {
|
|||
case "xor2-encoding":
|
||||
c.tsdb.EnableXOR2Encoding = true
|
||||
logger.Info("Experimental XOR2 chunk encoding enabled.")
|
||||
case "st-synthesis":
|
||||
// TODO(ridwanmsharif): Move this to scrape configuration once stable.
|
||||
c.scrape.SynthesizeST = true
|
||||
features.Enable(features.Scrape, "st-synthesis")
|
||||
logger.Info("Experimental start timestamp synthesis enabled.")
|
||||
case "st-storage":
|
||||
c.scrape.ParseST = true
|
||||
c.tsdb.EnableSTStorage = true
|
||||
|
|
@ -334,6 +337,9 @@ func (c *flagConfig) setFeatureListOptions(logger *slog.Logger) error {
|
|||
case "fast-startup":
|
||||
c.tsdb.EnableFastStartup = true
|
||||
logger.Info("Experimental fast startup is enabled.")
|
||||
case "search-api":
|
||||
c.web.EnableSearch = true
|
||||
logger.Info("Experimental search API enabled.")
|
||||
default:
|
||||
logger.Warn("Unknown option for --enable-feature", "option", o)
|
||||
}
|
||||
|
|
@ -398,7 +404,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.").
|
||||
|
|
@ -577,6 +586,9 @@ func main() {
|
|||
serverOnlyFlag(a, "storage.remote.read-max-bytes-in-frame", "Maximum number of bytes in a single frame for streaming remote read response types before marshalling. Note that client might have limit on frame size as well. 1MB as recommended by protobuf by default.").
|
||||
Default("1048576").IntVar(&cfg.web.RemoteReadBytesInFrame)
|
||||
|
||||
serverOnlyFlag(a, "web.search.max-limit", "Hard upper bound on the \"limit\" query parameter accepted by the experimental search API (--enable-feature=search-api). Requests with a higher limit are rejected with HTTP 400. 0 disables the cap.").
|
||||
Default("10000").IntVar(&cfg.web.MaxSearchLimit)
|
||||
|
||||
serverOnlyFlag(a, "rules.alert.for-outage-tolerance", "Max time to tolerate prometheus outage for restoring \"for\" state of alert.").
|
||||
Default("1h").SetValue(&cfg.outageTolerance)
|
||||
|
||||
|
|
@ -619,7 +631,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-duration-expr, promql-experimental-functions, promql-extended-range-selectors, promql-per-step-stats, search-api, st-storage, st-synthesis, 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 +667,18 @@ 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)
|
||||
}
|
||||
|
||||
if cfg.web.MaxSearchLimit < 0 {
|
||||
fmt.Fprintf(os.Stderr, "--web.search.max-limit must be non-negative; got %d (use 0 to disable the cap)\n", cfg.web.MaxSearchLimit)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
promqlParser := parser.NewParser(cfg.parserOpts)
|
||||
|
||||
if agentMode && len(serverOnlyFlags) > 0 {
|
||||
|
|
@ -817,7 +841,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)
|
||||
}
|
||||
|
|
@ -1749,6 +1773,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 {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
7
cmd/prometheus/testdata/features.json
vendored
7
cmd/prometheus/testdata/features.json
vendored
|
|
@ -10,6 +10,9 @@
|
|||
"query_stats": true,
|
||||
"query_warnings": true,
|
||||
"remote_write_receiver": false,
|
||||
"search": false,
|
||||
"search_fuzz_alg_jarowinkler": true,
|
||||
"search_fuzz_alg_subsequence": true,
|
||||
"time_range_labels": true,
|
||||
"time_range_series": true
|
||||
},
|
||||
|
|
@ -29,7 +32,7 @@
|
|||
"bool": true,
|
||||
"by": true,
|
||||
"delayed_name_removal": false,
|
||||
"duration_expr": true,
|
||||
"duration_expr": false,
|
||||
"fill": false,
|
||||
"fill_left": false,
|
||||
"fill_right": false,
|
||||
|
|
@ -97,7 +100,9 @@
|
|||
"log10": true,
|
||||
"log2": true,
|
||||
"mad_over_time": false,
|
||||
"max_of": false,
|
||||
"max_over_time": true,
|
||||
"min_of": false,
|
||||
"min_over_time": true,
|
||||
"minute": true,
|
||||
"month": true,
|
||||
|
|
|
|||
|
|
@ -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 "":
|
||||
|
|
|
|||
|
|
@ -55,12 +55,14 @@ func TestSDCheckResult(t *testing.T) {
|
|||
{
|
||||
DiscoveredLabels: labels.FromStrings(
|
||||
"__address__", "localhost:8080",
|
||||
"__convert_classic_histograms_to_nhcb__", "false",
|
||||
"__scrape_interval__", "1m",
|
||||
"__scrape_timeout__", "10s",
|
||||
"foo", "bar",
|
||||
),
|
||||
Labels: labels.FromStrings(
|
||||
"__address__", "localhost:8080",
|
||||
"__convert_classic_histograms_to_nhcb__", "false",
|
||||
"__scrape_interval__", "1m",
|
||||
"__scrape_timeout__", "10s",
|
||||
"foo", "bar",
|
||||
|
|
|
|||
|
|
@ -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-20260518105423-c9d5bc4c50a9 // 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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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-20260518105423-c9d5bc4c50a9 h1:e33IfrrwrJkylWwAGcQ2jMvbWVv13lv0suTXjGNeiqY=
|
||||
github.com/prometheus/client_golang/exp v0.0.0-20260518105423-c9d5bc4c50a9/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=
|
||||
|
|
|
|||
|
|
@ -1512,6 +1512,10 @@ func (c *RemoteWriteConfig) UnmarshalYAML(unmarshal func(any) error) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := c.QueueConfig.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return validateAuthConfigs(c)
|
||||
}
|
||||
|
||||
|
|
@ -1604,6 +1608,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 {
|
||||
|
|
|
|||
|
|
@ -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.")
|
||||
}
|
||||
|
|
@ -2460,6 +2462,30 @@ var expectedErrors = []struct {
|
|||
filename: "remote_write_auth_exclusive.bad.yml",
|
||||
errMsg: "at most one of basic_auth, authorization, oauth2, sigv4, azuread or google_iam must be configured",
|
||||
},
|
||||
{
|
||||
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`,
|
||||
},
|
||||
{
|
||||
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"`,
|
||||
|
|
|
|||
2
config/testdata/conf.good.yml
vendored
2
config/testdata/conf.good.yml
vendored
|
|
@ -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
|
||||
|
||||
|
|
|
|||
4
config/testdata/remote_write_queue_capacity_zero.bad.yml
vendored
Normal file
4
config/testdata/remote_write_queue_capacity_zero.bad.yml
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
remote_write:
|
||||
- url: http://localhost:9090/api/v1/write
|
||||
queue_config:
|
||||
capacity: 0
|
||||
5
config/testdata/remote_write_queue_max_backoff_less_than_min.bad.yml
vendored
Normal file
5
config/testdata/remote_write_queue_max_backoff_less_than_min.bad.yml
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
remote_write:
|
||||
- url: http://localhost:9090/api/v1/write
|
||||
queue_config:
|
||||
min_backoff: 10s
|
||||
max_backoff: 1s
|
||||
4
config/testdata/remote_write_queue_max_samples_per_send_zero.bad.yml
vendored
Normal file
4
config/testdata/remote_write_queue_max_samples_per_send_zero.bad.yml
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
remote_write:
|
||||
- url: http://localhost:9090/api/v1/write
|
||||
queue_config:
|
||||
max_samples_per_send: 0
|
||||
4
config/testdata/remote_write_queue_max_shards_zero.bad.yml
vendored
Normal file
4
config/testdata/remote_write_queue_max_shards_zero.bad.yml
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
remote_write:
|
||||
- url: http://localhost:9090/api/v1/write
|
||||
queue_config:
|
||||
max_shards: 0
|
||||
5
config/testdata/remote_write_queue_min_shards_greater_than_max.bad.yml
vendored
Normal file
5
config/testdata/remote_write_queue_min_shards_greater_than_max.bad.yml
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
remote_write:
|
||||
- url: http://localhost:9090/api/v1/write
|
||||
queue_config:
|
||||
min_shards: 100
|
||||
max_shards: 10
|
||||
4
config/testdata/remote_write_queue_min_shards_zero.bad.yml
vendored
Normal file
4
config/testdata/remote_write_queue_min_shards_zero.bad.yml
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
remote_write:
|
||||
- url: http://localhost:9090/api/v1/write
|
||||
queue_config:
|
||||
min_shards: 0
|
||||
|
|
@ -30,6 +30,7 @@ import (
|
|||
)
|
||||
|
||||
func TestRoleUnmarshalYAML(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
|
|
@ -84,6 +85,7 @@ func TestRoleUnmarshalYAML(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestRoleString(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
role Role
|
||||
|
|
@ -114,16 +116,19 @@ func TestRoleString(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSDConfigName(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := &SDConfig{}
|
||||
require.Equal(t, "aws", cfg.Name())
|
||||
}
|
||||
|
||||
func TestDefaultSDConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
require.Equal(t, Role(""), DefaultSDConfig.Role)
|
||||
require.Equal(t, model.Duration(60*time.Second), DefaultSDConfig.RefreshInterval)
|
||||
}
|
||||
|
||||
func TestSDConfigUnmarshalYAML(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
yaml string
|
||||
|
|
@ -189,6 +194,7 @@ port: 9300`,
|
|||
// all configs pointed to the same global default, causing port and other
|
||||
// settings from one job to overwrite settings in another job.
|
||||
func TestMultipleSDConfigsDoNotShareState(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
yaml string
|
||||
|
|
@ -489,6 +495,7 @@ region = ` + randomRegion + `
|
|||
}
|
||||
|
||||
func TestSDConfigSetDirectory(t *testing.T) {
|
||||
t.Parallel()
|
||||
tmpDir := t.TempDir()
|
||||
tests := []struct {
|
||||
name string
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -149,6 +150,47 @@ type ec2Client interface {
|
|||
DescribeInstances(ctx context.Context, params *ec2.DescribeInstancesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeInstancesOutput, error)
|
||||
}
|
||||
|
||||
// ec2ClientAdapter holds the EC2 API calls that AWS discovery actually uses as
|
||||
// method-value closures over the concrete *ec2.Client.
|
||||
//
|
||||
// It exists purely to keep the binary small. The Go linker, once reflection
|
||||
// (reflect.Value.Method/Call plus struct-field traversal, both reachable via
|
||||
// the YAML/config machinery) is live, conservatively retains every exported
|
||||
// method of any concrete type that is reachable through an interface — and a
|
||||
// type stored as a field of an interface-boxed struct counts. *ec2.Client has
|
||||
// ~470 operation methods; retaining all of them pulls in ~1,500 serializers and
|
||||
// roughly 21 MB. By capturing only the needed methods as func values, the
|
||||
// concrete *ec2.Client is hidden inside closure contexts (which reflection
|
||||
// cannot traverse) and never appears as a field of a boxed type, so dead-code
|
||||
// elimination drops the unused operations.
|
||||
type ec2ClientAdapter struct {
|
||||
describeAvailabilityZones func(ctx context.Context, params *ec2.DescribeAvailabilityZonesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeAvailabilityZonesOutput, error)
|
||||
describeInstances func(ctx context.Context, params *ec2.DescribeInstancesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeInstancesOutput, error)
|
||||
describeNetworkInterfaces func(ctx context.Context, params *ec2.DescribeNetworkInterfacesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeNetworkInterfacesOutput, error)
|
||||
}
|
||||
|
||||
// newEC2ClientAdapter wraps a concrete *ec2.Client, capturing only the API
|
||||
// calls AWS discovery needs. See the ec2ClientAdapter doc comment for why.
|
||||
func newEC2ClientAdapter(c *ec2.Client) ec2ClientAdapter {
|
||||
return ec2ClientAdapter{
|
||||
describeAvailabilityZones: c.DescribeAvailabilityZones,
|
||||
describeInstances: c.DescribeInstances,
|
||||
describeNetworkInterfaces: c.DescribeNetworkInterfaces,
|
||||
}
|
||||
}
|
||||
|
||||
func (a ec2ClientAdapter) DescribeAvailabilityZones(ctx context.Context, params *ec2.DescribeAvailabilityZonesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeAvailabilityZonesOutput, error) {
|
||||
return a.describeAvailabilityZones(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a ec2ClientAdapter) DescribeInstances(ctx context.Context, params *ec2.DescribeInstancesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeInstancesOutput, error) {
|
||||
return a.describeInstances(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a ec2ClientAdapter) DescribeNetworkInterfaces(ctx context.Context, params *ec2.DescribeNetworkInterfacesInput, optFns ...func(*ec2.Options)) (*ec2.DescribeNetworkInterfacesOutput, error) {
|
||||
return a.describeNetworkInterfaces(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
// EC2Discovery periodically performs EC2-SD requests. It implements
|
||||
// the Discoverer interface.
|
||||
type EC2Discovery struct {
|
||||
|
|
@ -234,12 +276,12 @@ func (d *EC2Discovery) ec2Client(ctx context.Context) (ec2Client, error) {
|
|||
cfg.Credentials = aws.NewCredentialsCache(assumeProvider)
|
||||
}
|
||||
|
||||
d.ec2 = ec2.NewFromConfig(cfg, func(options *ec2.Options) {
|
||||
d.ec2 = newEC2ClientAdapter(ec2.NewFromConfig(cfg, func(options *ec2.Options) {
|
||||
if d.cfg.Endpoint != "" {
|
||||
options.BaseEndpoint = &d.cfg.Endpoint
|
||||
}
|
||||
options.HTTPClient = httpClient
|
||||
})
|
||||
}))
|
||||
|
||||
return d.ec2, nil
|
||||
}
|
||||
|
|
@ -306,7 +348,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 +363,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 +386,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 +426,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 +436,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 +457,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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ func TestMain(m *testing.M) {
|
|||
}
|
||||
|
||||
func TestEC2DiscoveryRefreshAZIDs(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
// iterate through the test cases
|
||||
|
|
@ -99,6 +100,7 @@ func TestEC2DiscoveryRefreshAZIDs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestEC2DiscoveryRefresh(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
// iterate through the test cases
|
||||
|
|
@ -108,7 +110,7 @@ func TestEC2DiscoveryRefresh(t *testing.T) {
|
|||
expected []*targetgroup.Group
|
||||
}{
|
||||
{
|
||||
name: "NoPrivateIp",
|
||||
name: "NoPrivateIpOrIpv6",
|
||||
ec2Data: &ec2DataStore{
|
||||
region: "region-noprivateip",
|
||||
azToAZID: map[string]string{
|
||||
|
|
@ -351,6 +353,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 +365,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)
|
||||
|
|
|
|||
|
|
@ -162,6 +162,60 @@ type ecsClient interface {
|
|||
DescribeContainerInstances(context.Context, *ecs.DescribeContainerInstancesInput, ...func(*ecs.Options)) (*ecs.DescribeContainerInstancesOutput, error)
|
||||
}
|
||||
|
||||
// ecsClientAdapter captures only the ECS API calls AWS discovery uses as
|
||||
// method-value closures, keeping the concrete *ecs.Client out of any
|
||||
// interface-boxed struct field. See ec2ClientAdapter for the full rationale:
|
||||
// this stops the linker from retaining the entire ECS API surface (~2 MB).
|
||||
type ecsClientAdapter struct {
|
||||
listClusters func(context.Context, *ecs.ListClustersInput, ...func(*ecs.Options)) (*ecs.ListClustersOutput, error)
|
||||
describeClusters func(context.Context, *ecs.DescribeClustersInput, ...func(*ecs.Options)) (*ecs.DescribeClustersOutput, error)
|
||||
listServices func(context.Context, *ecs.ListServicesInput, ...func(*ecs.Options)) (*ecs.ListServicesOutput, error)
|
||||
describeServices func(context.Context, *ecs.DescribeServicesInput, ...func(*ecs.Options)) (*ecs.DescribeServicesOutput, error)
|
||||
listTasks func(context.Context, *ecs.ListTasksInput, ...func(*ecs.Options)) (*ecs.ListTasksOutput, error)
|
||||
describeTasks func(context.Context, *ecs.DescribeTasksInput, ...func(*ecs.Options)) (*ecs.DescribeTasksOutput, error)
|
||||
describeContainerInstances func(context.Context, *ecs.DescribeContainerInstancesInput, ...func(*ecs.Options)) (*ecs.DescribeContainerInstancesOutput, error)
|
||||
}
|
||||
|
||||
func newECSClientAdapter(c *ecs.Client) ecsClientAdapter {
|
||||
return ecsClientAdapter{
|
||||
listClusters: c.ListClusters,
|
||||
describeClusters: c.DescribeClusters,
|
||||
listServices: c.ListServices,
|
||||
describeServices: c.DescribeServices,
|
||||
listTasks: c.ListTasks,
|
||||
describeTasks: c.DescribeTasks,
|
||||
describeContainerInstances: c.DescribeContainerInstances,
|
||||
}
|
||||
}
|
||||
|
||||
func (a ecsClientAdapter) ListClusters(ctx context.Context, params *ecs.ListClustersInput, optFns ...func(*ecs.Options)) (*ecs.ListClustersOutput, error) {
|
||||
return a.listClusters(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a ecsClientAdapter) DescribeClusters(ctx context.Context, params *ecs.DescribeClustersInput, optFns ...func(*ecs.Options)) (*ecs.DescribeClustersOutput, error) {
|
||||
return a.describeClusters(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a ecsClientAdapter) ListServices(ctx context.Context, params *ecs.ListServicesInput, optFns ...func(*ecs.Options)) (*ecs.ListServicesOutput, error) {
|
||||
return a.listServices(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a ecsClientAdapter) DescribeServices(ctx context.Context, params *ecs.DescribeServicesInput, optFns ...func(*ecs.Options)) (*ecs.DescribeServicesOutput, error) {
|
||||
return a.describeServices(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a ecsClientAdapter) ListTasks(ctx context.Context, params *ecs.ListTasksInput, optFns ...func(*ecs.Options)) (*ecs.ListTasksOutput, error) {
|
||||
return a.listTasks(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a ecsClientAdapter) DescribeTasks(ctx context.Context, params *ecs.DescribeTasksInput, optFns ...func(*ecs.Options)) (*ecs.DescribeTasksOutput, error) {
|
||||
return a.describeTasks(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a ecsClientAdapter) DescribeContainerInstances(ctx context.Context, params *ecs.DescribeContainerInstancesInput, optFns ...func(*ecs.Options)) (*ecs.DescribeContainerInstancesOutput, error) {
|
||||
return a.describeContainerInstances(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
type ecsEC2Client interface {
|
||||
DescribeInstances(context.Context, *ec2.DescribeInstancesInput, ...func(*ec2.Options)) (*ec2.DescribeInstancesOutput, error)
|
||||
DescribeNetworkInterfaces(context.Context, *ec2.DescribeNetworkInterfacesInput, ...func(*ec2.Options)) (*ec2.DescribeNetworkInterfacesOutput, error)
|
||||
|
|
@ -250,16 +304,16 @@ func (d *ECSDiscovery) initEcsClient(ctx context.Context) error {
|
|||
cfg.Credentials = aws.NewCredentialsCache(assumeProvider)
|
||||
}
|
||||
|
||||
d.ecs = ecs.NewFromConfig(cfg, func(options *ecs.Options) {
|
||||
d.ecs = newECSClientAdapter(ecs.NewFromConfig(cfg, func(options *ecs.Options) {
|
||||
if d.cfg.Endpoint != "" {
|
||||
options.BaseEndpoint = &d.cfg.Endpoint
|
||||
}
|
||||
options.HTTPClient = client
|
||||
})
|
||||
}))
|
||||
|
||||
d.ec2 = ec2.NewFromConfig(cfg, func(options *ec2.Options) {
|
||||
d.ec2 = newEC2ClientAdapter(ec2.NewFromConfig(cfg, func(options *ec2.Options) {
|
||||
options.HTTPClient = client
|
||||
})
|
||||
}))
|
||||
|
||||
// Test credentials by making a simple API call
|
||||
testCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ type ecsDataStore struct {
|
|||
}
|
||||
|
||||
func TestECSDiscoveryListClusterARNs(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
// iterate through the test cases
|
||||
|
|
@ -114,6 +115,7 @@ func TestECSDiscoveryListClusterARNs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestECSDiscoveryDescribeClusters(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
// iterate through the test cases
|
||||
|
|
@ -212,6 +214,7 @@ func TestECSDiscoveryDescribeClusters(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestECSDiscoveryListServiceARNs(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range []struct {
|
||||
|
|
@ -310,6 +313,7 @@ func TestECSDiscoveryListServiceARNs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestECSDiscoveryDescribeServices(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range []struct {
|
||||
|
|
@ -402,6 +406,7 @@ func TestECSDiscoveryDescribeServices(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestECSDiscoveryDescribeContainerInstances(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range []struct {
|
||||
|
|
@ -506,6 +511,7 @@ func TestECSDiscoveryDescribeContainerInstances(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestECSDiscoveryDescribeEC2Instances(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range []struct {
|
||||
|
|
@ -619,6 +625,7 @@ func TestECSDiscoveryDescribeEC2Instances(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestECSDiscoveryDescribeNetworkInterfaces(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range []struct {
|
||||
|
|
@ -760,6 +767,7 @@ func TestECSDiscoveryDescribeNetworkInterfaces(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestECSDiscoveryListTaskARNs(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
// iterate through the test cases
|
||||
|
|
@ -834,6 +842,7 @@ func TestECSDiscoveryListTaskARNs(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestECSDiscoveryDescribeTasks(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
// iterate through the test cases
|
||||
|
|
@ -923,6 +932,7 @@ func TestECSDiscoveryDescribeTasks(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestECSDiscoveryRefresh(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
tests := []struct {
|
||||
|
|
@ -1712,6 +1722,7 @@ func (m *mockECSEC2Client) DescribeNetworkInterfaces(_ context.Context, input *e
|
|||
}
|
||||
|
||||
func TestIsStandaloneTask(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
task ecsTypes.Task
|
||||
|
|
@ -1763,6 +1774,7 @@ func TestIsStandaloneTask(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetServiceNameFromTaskGroup(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
task ecsTypes.Task
|
||||
|
|
|
|||
|
|
@ -246,6 +246,37 @@ type elasticacheClient interface {
|
|||
ListTagsForResource(ctx context.Context, params *elasticache.ListTagsForResourceInput, optFns ...func(*elasticache.Options)) (*elasticache.ListTagsForResourceOutput, error)
|
||||
}
|
||||
|
||||
// elasticacheClientAdapter captures only the ElastiCache API calls AWS
|
||||
// discovery uses as method-value closures, keeping the concrete
|
||||
// *elasticache.Client out of any interface-boxed struct field. See
|
||||
// ec2ClientAdapter for the full rationale: this stops the linker from retaining
|
||||
// the entire ElastiCache API surface (~2.5 MB).
|
||||
type elasticacheClientAdapter struct {
|
||||
describeServerlessCaches func(ctx context.Context, params *elasticache.DescribeServerlessCachesInput, optFns ...func(*elasticache.Options)) (*elasticache.DescribeServerlessCachesOutput, error)
|
||||
describeCacheClusters func(ctx context.Context, params *elasticache.DescribeCacheClustersInput, optFns ...func(*elasticache.Options)) (*elasticache.DescribeCacheClustersOutput, error)
|
||||
listTagsForResource func(ctx context.Context, params *elasticache.ListTagsForResourceInput, optFns ...func(*elasticache.Options)) (*elasticache.ListTagsForResourceOutput, error)
|
||||
}
|
||||
|
||||
func newElastiCacheClientAdapter(c *elasticache.Client) elasticacheClientAdapter {
|
||||
return elasticacheClientAdapter{
|
||||
describeServerlessCaches: c.DescribeServerlessCaches,
|
||||
describeCacheClusters: c.DescribeCacheClusters,
|
||||
listTagsForResource: c.ListTagsForResource,
|
||||
}
|
||||
}
|
||||
|
||||
func (a elasticacheClientAdapter) DescribeServerlessCaches(ctx context.Context, params *elasticache.DescribeServerlessCachesInput, optFns ...func(*elasticache.Options)) (*elasticache.DescribeServerlessCachesOutput, error) {
|
||||
return a.describeServerlessCaches(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a elasticacheClientAdapter) DescribeCacheClusters(ctx context.Context, params *elasticache.DescribeCacheClustersInput, optFns ...func(*elasticache.Options)) (*elasticache.DescribeCacheClustersOutput, error) {
|
||||
return a.describeCacheClusters(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a elasticacheClientAdapter) ListTagsForResource(ctx context.Context, params *elasticache.ListTagsForResourceInput, optFns ...func(*elasticache.Options)) (*elasticache.ListTagsForResourceOutput, error) {
|
||||
return a.listTagsForResource(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
// ElasticacheDiscovery periodically performs Elasticache-SD requests.
|
||||
// It implements the Discoverer interface.
|
||||
type ElasticacheDiscovery struct {
|
||||
|
|
@ -328,12 +359,12 @@ func (d *ElasticacheDiscovery) initElasticacheClient(ctx context.Context) error
|
|||
cfg.Credentials = aws.NewCredentialsCache(assumeProvider)
|
||||
}
|
||||
|
||||
d.elasticacheClient = elasticache.NewFromConfig(cfg, func(options *elasticache.Options) {
|
||||
d.elasticacheClient = newElastiCacheClientAdapter(elasticache.NewFromConfig(cfg, func(options *elasticache.Options) {
|
||||
if d.cfg.Endpoint != "" {
|
||||
options.BaseEndpoint = &d.cfg.Endpoint
|
||||
}
|
||||
options.HTTPClient = client
|
||||
})
|
||||
}))
|
||||
|
||||
// Test credentials by making a simple API call
|
||||
testCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ type elasticacheDataStore struct {
|
|||
}
|
||||
|
||||
func TestElasticacheDiscoveryDescribeServerlessCaches(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range []struct {
|
||||
|
|
@ -125,6 +126,7 @@ func TestElasticacheDiscoveryDescribeServerlessCaches(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestElasticacheDiscoveryDescribeCacheClusters(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range []struct {
|
||||
|
|
@ -184,6 +186,7 @@ func TestElasticacheDiscoveryDescribeCacheClusters(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAddServerlessCacheTargets(t *testing.T) {
|
||||
t.Parallel()
|
||||
testTime := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
tests := []struct {
|
||||
|
|
@ -269,6 +272,7 @@ func TestAddServerlessCacheTargets(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAddCacheClusterTargets(t *testing.T) {
|
||||
t.Parallel()
|
||||
testTime := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
tests := []struct {
|
||||
|
|
@ -532,6 +536,7 @@ func (m *mockElasticacheClient) ListTagsForResource(_ context.Context, input *el
|
|||
}
|
||||
|
||||
func TestSplitCacheDeploymentOptions(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
caches []string
|
||||
|
|
|
|||
|
|
@ -119,12 +119,29 @@ func (c *LightsailSDConfig) UnmarshalYAML(unmarshal func(any) error) error {
|
|||
return c.HTTPClientConfig.Validate()
|
||||
}
|
||||
|
||||
// lightsailClientAdapter captures only the Lightsail API calls AWS discovery
|
||||
// uses as method-value closures, keeping the concrete *lightsail.Client out of
|
||||
// any interface-boxed struct field. See ec2ClientAdapter for the full
|
||||
// rationale: this stops the linker from retaining the entire Lightsail API
|
||||
// surface (~3.4 MB).
|
||||
type lightsailClientAdapter struct {
|
||||
getInstances func(ctx context.Context, params *lightsail.GetInstancesInput, optFns ...func(*lightsail.Options)) (*lightsail.GetInstancesOutput, error)
|
||||
}
|
||||
|
||||
func newLightsailClientAdapter(c *lightsail.Client) *lightsailClientAdapter {
|
||||
return &lightsailClientAdapter{getInstances: c.GetInstances}
|
||||
}
|
||||
|
||||
func (a *lightsailClientAdapter) GetInstances(ctx context.Context, params *lightsail.GetInstancesInput, optFns ...func(*lightsail.Options)) (*lightsail.GetInstancesOutput, error) {
|
||||
return a.getInstances(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
// LightsailDiscovery periodically performs Lightsail-SD requests. It implements
|
||||
// the Discoverer interface.
|
||||
type LightsailDiscovery struct {
|
||||
*refresh.Discovery
|
||||
cfg *LightsailSDConfig
|
||||
lightsail *lightsail.Client
|
||||
lightsail *lightsailClientAdapter
|
||||
}
|
||||
|
||||
// NewLightsailDiscovery returns a new LightsailDiscovery which periodically refreshes its targets.
|
||||
|
|
@ -154,7 +171,7 @@ func NewLightsailDiscovery(conf *LightsailSDConfig, opts discovery.DiscovererOpt
|
|||
return d, nil
|
||||
}
|
||||
|
||||
func (d *LightsailDiscovery) lightsailClient(ctx context.Context) (*lightsail.Client, error) {
|
||||
func (d *LightsailDiscovery) lightsailClient(ctx context.Context) (*lightsailClientAdapter, error) {
|
||||
if d.lightsail != nil {
|
||||
return d.lightsail, nil
|
||||
}
|
||||
|
|
@ -198,12 +215,12 @@ func (d *LightsailDiscovery) lightsailClient(ctx context.Context) (*lightsail.Cl
|
|||
cfg.Credentials = aws.NewCredentialsCache(assumeProvider)
|
||||
}
|
||||
|
||||
d.lightsail = lightsail.NewFromConfig(cfg, func(options *lightsail.Options) {
|
||||
d.lightsail = newLightsailClientAdapter(lightsail.NewFromConfig(cfg, func(options *lightsail.Options) {
|
||||
if d.cfg.Endpoint != "" {
|
||||
options.BaseEndpoint = &d.cfg.Endpoint
|
||||
}
|
||||
options.HTTPClient = httpClient
|
||||
})
|
||||
}))
|
||||
|
||||
return d.lightsail, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,6 +158,36 @@ type mskClient interface {
|
|||
ListNodes(context.Context, *kafka.ListNodesInput, ...func(*kafka.Options)) (*kafka.ListNodesOutput, error)
|
||||
}
|
||||
|
||||
// mskClientAdapter captures only the MSK (Kafka) API calls AWS discovery uses
|
||||
// as method-value closures, keeping the concrete *kafka.Client out of any
|
||||
// interface-boxed struct field. See ec2ClientAdapter for the full rationale:
|
||||
// this stops the linker from retaining the entire MSK API surface (~1.4 MB).
|
||||
type mskClientAdapter struct {
|
||||
describeClusterV2 func(context.Context, *kafka.DescribeClusterV2Input, ...func(*kafka.Options)) (*kafka.DescribeClusterV2Output, error)
|
||||
listClustersV2 func(context.Context, *kafka.ListClustersV2Input, ...func(*kafka.Options)) (*kafka.ListClustersV2Output, error)
|
||||
listNodes func(context.Context, *kafka.ListNodesInput, ...func(*kafka.Options)) (*kafka.ListNodesOutput, error)
|
||||
}
|
||||
|
||||
func newMSKClientAdapter(c *kafka.Client) mskClientAdapter {
|
||||
return mskClientAdapter{
|
||||
describeClusterV2: c.DescribeClusterV2,
|
||||
listClustersV2: c.ListClustersV2,
|
||||
listNodes: c.ListNodes,
|
||||
}
|
||||
}
|
||||
|
||||
func (a mskClientAdapter) DescribeClusterV2(ctx context.Context, params *kafka.DescribeClusterV2Input, optFns ...func(*kafka.Options)) (*kafka.DescribeClusterV2Output, error) {
|
||||
return a.describeClusterV2(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a mskClientAdapter) ListClustersV2(ctx context.Context, params *kafka.ListClustersV2Input, optFns ...func(*kafka.Options)) (*kafka.ListClustersV2Output, error) {
|
||||
return a.listClustersV2(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a mskClientAdapter) ListNodes(ctx context.Context, params *kafka.ListNodesInput, optFns ...func(*kafka.Options)) (*kafka.ListNodesOutput, error) {
|
||||
return a.listNodes(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
// MSKDiscovery periodically performs MSK-SD requests. It implements
|
||||
// the Discoverer interface.
|
||||
type MSKDiscovery struct {
|
||||
|
|
@ -240,12 +270,12 @@ func (d *MSKDiscovery) initMskClient(ctx context.Context) error {
|
|||
cfg.Credentials = aws.NewCredentialsCache(assumeProvider)
|
||||
}
|
||||
|
||||
d.msk = kafka.NewFromConfig(cfg, func(options *kafka.Options) {
|
||||
d.msk = newMSKClientAdapter(kafka.NewFromConfig(cfg, func(options *kafka.Options) {
|
||||
if d.cfg.Endpoint != "" {
|
||||
options.BaseEndpoint = &d.cfg.Endpoint
|
||||
}
|
||||
options.HTTPClient = client
|
||||
})
|
||||
}))
|
||||
|
||||
// Test credentials by making a simple API call
|
||||
testCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ type mskDataStore struct {
|
|||
}
|
||||
|
||||
func TestMSKDiscoveryListClusters(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range []struct {
|
||||
|
|
@ -126,6 +127,7 @@ func TestMSKDiscoveryListClusters(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMSKDiscoveryDescribeClusters(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range []struct {
|
||||
|
|
@ -240,6 +242,7 @@ func TestMSKDiscoveryDescribeClusters(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMSKDiscoveryListNodes(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
for _, tt := range []struct {
|
||||
|
|
@ -406,6 +409,7 @@ func TestMSKDiscoveryListNodes(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMSKDiscoveryRefresh(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
|
||||
tests := []struct {
|
||||
|
|
@ -1031,6 +1035,7 @@ func TestMSKDiscoveryRefresh(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNodeType(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
node types.NodeInfo
|
||||
|
|
|
|||
|
|
@ -276,6 +276,30 @@ type rdsClient interface {
|
|||
DescribeDBInstances(context.Context, *rds.DescribeDBInstancesInput, ...func(*rds.Options)) (*rds.DescribeDBInstancesOutput, error)
|
||||
}
|
||||
|
||||
// rdsClientAdapter captures only the RDS API calls AWS discovery uses as
|
||||
// method-value closures, keeping the concrete *rds.Client out of any
|
||||
// interface-boxed struct field. See ec2ClientAdapter for the full rationale:
|
||||
// this stops the linker from retaining the entire RDS API surface (~5 MB).
|
||||
type rdsClientAdapter struct {
|
||||
describeDBClusters func(context.Context, *rds.DescribeDBClustersInput, ...func(*rds.Options)) (*rds.DescribeDBClustersOutput, error)
|
||||
describeDBInstances func(context.Context, *rds.DescribeDBInstancesInput, ...func(*rds.Options)) (*rds.DescribeDBInstancesOutput, error)
|
||||
}
|
||||
|
||||
func newRDSClientAdapter(c *rds.Client) rdsClientAdapter {
|
||||
return rdsClientAdapter{
|
||||
describeDBClusters: c.DescribeDBClusters,
|
||||
describeDBInstances: c.DescribeDBInstances,
|
||||
}
|
||||
}
|
||||
|
||||
func (a rdsClientAdapter) DescribeDBClusters(ctx context.Context, params *rds.DescribeDBClustersInput, optFns ...func(*rds.Options)) (*rds.DescribeDBClustersOutput, error) {
|
||||
return a.describeDBClusters(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
func (a rdsClientAdapter) DescribeDBInstances(ctx context.Context, params *rds.DescribeDBInstancesInput, optFns ...func(*rds.Options)) (*rds.DescribeDBInstancesOutput, error) {
|
||||
return a.describeDBInstances(ctx, params, optFns...)
|
||||
}
|
||||
|
||||
// RDSDiscovery periodically performs RDS-SD requests. It implements
|
||||
// the Discoverer interface.
|
||||
type RDSDiscovery struct {
|
||||
|
|
@ -358,12 +382,12 @@ func (d *RDSDiscovery) initRdsClient(ctx context.Context) error {
|
|||
cfg.Credentials = aws.NewCredentialsCache(assumeProvider)
|
||||
}
|
||||
|
||||
d.rds = rds.NewFromConfig(cfg, func(options *rds.Options) {
|
||||
d.rds = newRDSClientAdapter(rds.NewFromConfig(cfg, func(options *rds.Options) {
|
||||
if d.cfg.Endpoint != "" {
|
||||
options.BaseEndpoint = &d.cfg.Endpoint
|
||||
}
|
||||
options.HTTPClient = client
|
||||
})
|
||||
}))
|
||||
|
||||
// Test credentials by making a simple API call
|
||||
testCtx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
|
|
@ -462,9 +486,6 @@ func (d *RDSDiscovery) describeDBInstances(ctx context.Context, dbClusterARN str
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to describe DB instances for cluster ARN %s: %w", dbClusterARN, err)
|
||||
}
|
||||
if len(output.DBInstances) == 0 {
|
||||
return nil, fmt.Errorf("no DB instances found for cluster ARN %s", dbClusterARN)
|
||||
}
|
||||
|
||||
for _, dbInstance := range output.DBInstances {
|
||||
mu.Lock()
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ func (m *mockRDSClient) DescribeDBInstances(_ context.Context, input *rds.Descri
|
|||
}
|
||||
|
||||
func TestRDSDiscoveryRefresh(t *testing.T) {
|
||||
t.Parallel()
|
||||
testTime := time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
tests := []struct {
|
||||
|
|
@ -249,6 +250,21 @@ func TestRDSDiscoveryRefresh(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NoInstancesInCluster",
|
||||
clusters: map[string]types.DBCluster{
|
||||
"arn:aws:rds:us-west-2:123456789012:cluster:prod-cluster": {
|
||||
DBClusterArn: aws.String("arn:aws:rds:us-west-2:123456789012:cluster:prod-cluster"),
|
||||
DBClusterIdentifier: aws.String("prod-cluster"),
|
||||
Engine: aws.String("aurora-mysql"),
|
||||
EngineVersion: aws.String("8.0.mysql_aurora.3.04.0"),
|
||||
Status: aws.String("available"),
|
||||
DBClusterMembers: []types.DBClusterMember{},
|
||||
},
|
||||
},
|
||||
instances: map[string][]types.DBInstance{},
|
||||
expectedLabels: []model.LabelSet{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
@ -421,6 +437,7 @@ func TestRDSDiscoveryRefresh(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestDescribeAllDBClusters(t *testing.T) {
|
||||
t.Parallel()
|
||||
mockClient := &mockRDSClient{
|
||||
clusters: map[string]types.DBCluster{
|
||||
"arn:aws:rds:us-east-1:123456789012:cluster:cluster-1": {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
|
||||
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5"
|
||||
|
|
@ -221,15 +222,105 @@ type client interface {
|
|||
|
||||
// azureClient represents multiple Azure Resource Manager providers.
|
||||
type azureClient struct {
|
||||
nic *armnetwork.InterfacesClient
|
||||
vm *armcompute.VirtualMachinesClient
|
||||
vmss *armcompute.VirtualMachineScaleSetsClient
|
||||
vmssvm *armcompute.VirtualMachineScaleSetVMsClient
|
||||
nic interfacesClientAdapter
|
||||
vm virtualMachinesClientAdapter
|
||||
vmss virtualMachineScaleSetsClientAdapter
|
||||
vmssvm virtualMachineScaleSetVMsClientAdapter
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
var _ client = &azureClient{}
|
||||
|
||||
// The *ClientAdapter types below capture only the operations discovery uses as
|
||||
// closures, hiding the concrete SDK clients from reflection so dead-code
|
||||
// elimination can drop the unused operations and shrink the binary.
|
||||
|
||||
// virtualMachinesClientAdapter adapts *armcompute.VirtualMachinesClient.
|
||||
type virtualMachinesClientAdapter struct {
|
||||
newListAllPager func(options *armcompute.VirtualMachinesClientListAllOptions) *runtime.Pager[armcompute.VirtualMachinesClientListAllResponse]
|
||||
newListPager func(resourceGroupName string, options *armcompute.VirtualMachinesClientListOptions) *runtime.Pager[armcompute.VirtualMachinesClientListResponse]
|
||||
}
|
||||
|
||||
func newVirtualMachinesClientAdapter(c *armcompute.VirtualMachinesClient) virtualMachinesClientAdapter {
|
||||
return virtualMachinesClientAdapter{
|
||||
newListAllPager: c.NewListAllPager,
|
||||
newListPager: c.NewListPager,
|
||||
}
|
||||
}
|
||||
|
||||
// NewListAllPager lists all virtual machines in the subscription.
|
||||
func (a virtualMachinesClientAdapter) NewListAllPager(options *armcompute.VirtualMachinesClientListAllOptions) *runtime.Pager[armcompute.VirtualMachinesClientListAllResponse] {
|
||||
return a.newListAllPager(options)
|
||||
}
|
||||
|
||||
// NewListPager lists the virtual machines in a resource group.
|
||||
func (a virtualMachinesClientAdapter) NewListPager(resourceGroupName string, options *armcompute.VirtualMachinesClientListOptions) *runtime.Pager[armcompute.VirtualMachinesClientListResponse] {
|
||||
return a.newListPager(resourceGroupName, options)
|
||||
}
|
||||
|
||||
// virtualMachineScaleSetsClientAdapter adapts *armcompute.VirtualMachineScaleSetsClient.
|
||||
type virtualMachineScaleSetsClientAdapter struct {
|
||||
newListAllPager func(options *armcompute.VirtualMachineScaleSetsClientListAllOptions) *runtime.Pager[armcompute.VirtualMachineScaleSetsClientListAllResponse]
|
||||
newListPager func(resourceGroupName string, options *armcompute.VirtualMachineScaleSetsClientListOptions) *runtime.Pager[armcompute.VirtualMachineScaleSetsClientListResponse]
|
||||
}
|
||||
|
||||
func newVirtualMachineScaleSetsClientAdapter(c *armcompute.VirtualMachineScaleSetsClient) virtualMachineScaleSetsClientAdapter {
|
||||
return virtualMachineScaleSetsClientAdapter{
|
||||
newListAllPager: c.NewListAllPager,
|
||||
newListPager: c.NewListPager,
|
||||
}
|
||||
}
|
||||
|
||||
// NewListAllPager lists all scale sets in the subscription.
|
||||
func (a virtualMachineScaleSetsClientAdapter) NewListAllPager(options *armcompute.VirtualMachineScaleSetsClientListAllOptions) *runtime.Pager[armcompute.VirtualMachineScaleSetsClientListAllResponse] {
|
||||
return a.newListAllPager(options)
|
||||
}
|
||||
|
||||
// NewListPager lists the scale sets in a resource group.
|
||||
func (a virtualMachineScaleSetsClientAdapter) NewListPager(resourceGroupName string, options *armcompute.VirtualMachineScaleSetsClientListOptions) *runtime.Pager[armcompute.VirtualMachineScaleSetsClientListResponse] {
|
||||
return a.newListPager(resourceGroupName, options)
|
||||
}
|
||||
|
||||
// virtualMachineScaleSetVMsClientAdapter adapts *armcompute.VirtualMachineScaleSetVMsClient.
|
||||
type virtualMachineScaleSetVMsClientAdapter struct {
|
||||
newListPager func(resourceGroupName, virtualMachineScaleSetName string, options *armcompute.VirtualMachineScaleSetVMsClientListOptions) *runtime.Pager[armcompute.VirtualMachineScaleSetVMsClientListResponse]
|
||||
}
|
||||
|
||||
func newVirtualMachineScaleSetVMsClientAdapter(c *armcompute.VirtualMachineScaleSetVMsClient) virtualMachineScaleSetVMsClientAdapter {
|
||||
return virtualMachineScaleSetVMsClientAdapter{
|
||||
newListPager: c.NewListPager,
|
||||
}
|
||||
}
|
||||
|
||||
// NewListPager lists the virtual machines of a scale set.
|
||||
func (a virtualMachineScaleSetVMsClientAdapter) NewListPager(resourceGroupName, virtualMachineScaleSetName string, options *armcompute.VirtualMachineScaleSetVMsClientListOptions) *runtime.Pager[armcompute.VirtualMachineScaleSetVMsClientListResponse] {
|
||||
return a.newListPager(resourceGroupName, virtualMachineScaleSetName, options)
|
||||
}
|
||||
|
||||
// interfacesClientAdapter adapts *armnetwork.InterfacesClient.
|
||||
type interfacesClientAdapter struct {
|
||||
get func(ctx context.Context, resourceGroupName, networkInterfaceName string, options *armnetwork.InterfacesClientGetOptions) (armnetwork.InterfacesClientGetResponse, error)
|
||||
|
||||
getVirtualMachineScaleSetNetworkInterface func(ctx context.Context, resourceGroupName, virtualMachineScaleSetName, virtualMachineIndex, networkInterfaceName string, options *armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceOptions) (armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceResponse, error)
|
||||
}
|
||||
|
||||
func newInterfacesClientAdapter(c *armnetwork.InterfacesClient) interfacesClientAdapter {
|
||||
return interfacesClientAdapter{
|
||||
get: c.Get,
|
||||
getVirtualMachineScaleSetNetworkInterface: c.GetVirtualMachineScaleSetNetworkInterface,
|
||||
}
|
||||
}
|
||||
|
||||
// Get retrieves a network interface.
|
||||
func (a interfacesClientAdapter) Get(ctx context.Context, resourceGroupName, networkInterfaceName string, options *armnetwork.InterfacesClientGetOptions) (armnetwork.InterfacesClientGetResponse, error) {
|
||||
return a.get(ctx, resourceGroupName, networkInterfaceName, options)
|
||||
}
|
||||
|
||||
// GetVirtualMachineScaleSetNetworkInterface retrieves a scale set VM network interface.
|
||||
func (a interfacesClientAdapter) GetVirtualMachineScaleSetNetworkInterface(ctx context.Context, resourceGroupName, virtualMachineScaleSetName, virtualMachineIndex, networkInterfaceName string, options *armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceOptions) (armnetwork.InterfacesClientGetVirtualMachineScaleSetNetworkInterfaceResponse, error) {
|
||||
return a.getVirtualMachineScaleSetNetworkInterface(ctx, resourceGroupName, virtualMachineScaleSetName, virtualMachineIndex, networkInterfaceName, options)
|
||||
}
|
||||
|
||||
// createAzureClient is a helper method for creating an Azure compute client to ARM.
|
||||
func (d *Discovery) createAzureClient() (client, error) {
|
||||
cloudConfiguration, err := CloudConfigurationFromName(d.cfg.Environment)
|
||||
|
|
@ -264,25 +355,29 @@ func (d *Discovery) createAzureClient() (client, error) {
|
|||
},
|
||||
}
|
||||
|
||||
c.vm, err = armcompute.NewVirtualMachinesClient(d.cfg.SubscriptionID, credential, options)
|
||||
vmClient, err := armcompute.NewVirtualMachinesClient(d.cfg.SubscriptionID, credential, options)
|
||||
if err != nil {
|
||||
return &azureClient{}, err
|
||||
}
|
||||
c.vm = newVirtualMachinesClientAdapter(vmClient)
|
||||
|
||||
c.nic, err = armnetwork.NewInterfacesClient(d.cfg.SubscriptionID, credential, options)
|
||||
nicClient, err := armnetwork.NewInterfacesClient(d.cfg.SubscriptionID, credential, options)
|
||||
if err != nil {
|
||||
return &azureClient{}, err
|
||||
}
|
||||
c.nic = newInterfacesClientAdapter(nicClient)
|
||||
|
||||
c.vmss, err = armcompute.NewVirtualMachineScaleSetsClient(d.cfg.SubscriptionID, credential, options)
|
||||
vmssClient, err := armcompute.NewVirtualMachineScaleSetsClient(d.cfg.SubscriptionID, credential, options)
|
||||
if err != nil {
|
||||
return &azureClient{}, err
|
||||
}
|
||||
c.vmss = newVirtualMachineScaleSetsClientAdapter(vmssClient)
|
||||
|
||||
c.vmssvm, err = armcompute.NewVirtualMachineScaleSetVMsClient(d.cfg.SubscriptionID, credential, options)
|
||||
vmssvmClient, err := armcompute.NewVirtualMachineScaleSetVMsClient(d.cfg.SubscriptionID, credential, options)
|
||||
if err != nil {
|
||||
return &azureClient{}, err
|
||||
}
|
||||
c.vmssvm = newVirtualMachineScaleSetVMsClientAdapter(vmssvmClient)
|
||||
|
||||
return &c, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -738,10 +738,10 @@ func createMockAzureClient(t *testing.T, vmResp []armcompute.VirtualMachinesClie
|
|||
|
||||
return &mockAzureClient{
|
||||
azureClient: azureClient{
|
||||
vm: vmClient,
|
||||
vmss: vmssClient,
|
||||
vmssvm: vmssvmClient,
|
||||
nic: interfacesClient,
|
||||
vm: newVirtualMachinesClientAdapter(vmClient),
|
||||
vmss: newVirtualMachineScaleSetsClientAdapter(vmssClient),
|
||||
vmssvm: newVirtualMachineScaleSetVMsClientAdapter(vmssvmClient),
|
||||
nic: newInterfacesClientAdapter(interfacesClient),
|
||||
logger: logger,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ func NewTestMetrics(t *testing.T, conf discovery.Config, reg prometheus.Register
|
|||
}
|
||||
|
||||
func TestConfiguredService(t *testing.T) {
|
||||
t.Parallel()
|
||||
conf := &SDConfig{
|
||||
Services: []string{"configuredServiceName"},
|
||||
}
|
||||
|
|
@ -64,6 +65,7 @@ func TestConfiguredService(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfiguredServiceWithTag(t *testing.T) {
|
||||
t.Parallel()
|
||||
conf := &SDConfig{
|
||||
Services: []string{"configuredServiceName"},
|
||||
ServiceTags: []string{"http"},
|
||||
|
|
@ -87,6 +89,7 @@ func TestConfiguredServiceWithTag(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConfiguredServiceWithTags(t *testing.T) {
|
||||
t.Parallel()
|
||||
type testcase struct {
|
||||
// What we've configured to watch.
|
||||
conf *SDConfig
|
||||
|
|
@ -174,6 +177,7 @@ func TestConfiguredServiceWithTags(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNonConfiguredService(t *testing.T) {
|
||||
t.Parallel()
|
||||
conf := &SDConfig{}
|
||||
|
||||
metrics := NewTestMetrics(t, conf, prometheus.NewRegistry())
|
||||
|
|
@ -294,6 +298,7 @@ func checkOneTarget(t *testing.T, tg []*targetgroup.Group) {
|
|||
|
||||
// Watch all the services in the catalog.
|
||||
func TestAllServices(t *testing.T) {
|
||||
t.Parallel()
|
||||
stub, config := newServer(t)
|
||||
t.Cleanup(stub.Close)
|
||||
|
||||
|
|
@ -313,6 +318,7 @@ func TestAllServices(t *testing.T) {
|
|||
|
||||
// targetgroup with no targets is emitted if no services were discovered.
|
||||
func TestNoTargets(t *testing.T) {
|
||||
t.Parallel()
|
||||
stub, config := newServer(t)
|
||||
t.Cleanup(stub.Close)
|
||||
config.ServiceTags = []string{"missing"}
|
||||
|
|
@ -334,6 +340,7 @@ func TestNoTargets(t *testing.T) {
|
|||
|
||||
// Watch only the test service.
|
||||
func TestOneService(t *testing.T) {
|
||||
t.Parallel()
|
||||
stub, config := newServer(t)
|
||||
t.Cleanup(stub.Close)
|
||||
|
||||
|
|
@ -349,6 +356,7 @@ func TestOneService(t *testing.T) {
|
|||
|
||||
// Watch the test service with a specific tag and node-meta.
|
||||
func TestAllOptions(t *testing.T) {
|
||||
t.Parallel()
|
||||
stub, config := newServer(t)
|
||||
t.Cleanup(stub.Close)
|
||||
|
||||
|
|
@ -374,6 +382,7 @@ func TestAllOptions(t *testing.T) {
|
|||
// TestFilterOption verifies that when services and filter are both configured, the Catalog API
|
||||
// is still called and receives the filter parameter, while the Health API does not.
|
||||
func TestFilterOption(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
catalogCalled bool
|
||||
catalogFilter string
|
||||
|
|
@ -432,6 +441,7 @@ func TestFilterOption(t *testing.T) {
|
|||
// TestHealthFilterOption verifies that health_filter is passed to the Health API and not to
|
||||
// the Catalog API.
|
||||
func TestHealthFilterOption(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
catalogCalled bool
|
||||
catalogFilter string
|
||||
|
|
@ -491,6 +501,7 @@ func TestHealthFilterOption(t *testing.T) {
|
|||
// TestBothFiltersOption verifies that when both filter and health_filter are configured,
|
||||
// each filter is sent exclusively to its respective API endpoint.
|
||||
func TestBothFiltersOption(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
catalogCalled bool
|
||||
catalogFilter string
|
||||
|
|
@ -548,6 +559,7 @@ func TestBothFiltersOption(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGetDatacenterShouldReturnError(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, tc := range []struct {
|
||||
handler func(http.ResponseWriter, *http.Request)
|
||||
errMessage string
|
||||
|
|
@ -592,6 +604,7 @@ func TestGetDatacenterShouldReturnError(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestUnmarshalConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
unmarshal := func(d []byte) func(any) error {
|
||||
return func(o any) error {
|
||||
return yaml.Unmarshal(d, o)
|
||||
|
|
@ -663,6 +676,7 @@ oauth2:
|
|||
|
||||
for _, test := range cases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
var config SDConfig
|
||||
err := config.UnmarshalYAML(unmarshal([]byte(test.config)))
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -113,18 +112,34 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(any) error) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// instancesLister lists the instances of a project/zone, paging through the
|
||||
// results and invoking f for each page.
|
||||
type instancesLister func(ctx context.Context, f func(*compute.InstanceList) error) error
|
||||
|
||||
// newInstancesLister captures *compute.Service in a closure instead of storing
|
||||
// it on the interface-boxed Discovery struct. This keeps the binary smaller:
|
||||
// otherwise reflection keeps every Compute method live, defeating dead-code
|
||||
// elimination.
|
||||
func newInstancesLister(svc *compute.Service, project, zone, filter string) instancesLister {
|
||||
isvc := compute.NewInstancesService(svc)
|
||||
return func(ctx context.Context, f func(*compute.InstanceList) error) error {
|
||||
ilc := isvc.List(project, zone)
|
||||
if filter != "" {
|
||||
ilc = ilc.Filter(filter)
|
||||
}
|
||||
return ilc.Pages(ctx, f)
|
||||
}
|
||||
}
|
||||
|
||||
// Discovery periodically performs GCE-SD requests. It implements
|
||||
// the Discoverer interface.
|
||||
type Discovery struct {
|
||||
*refresh.Discovery
|
||||
project string
|
||||
zone string
|
||||
filter string
|
||||
client *http.Client
|
||||
svc *compute.Service
|
||||
isvc *compute.InstancesService
|
||||
port int
|
||||
tagSeparator string
|
||||
project string
|
||||
zone string
|
||||
listInstances instancesLister
|
||||
port int
|
||||
tagSeparator string
|
||||
}
|
||||
|
||||
// NewDiscovery returns a new Discovery which periodically refreshes its targets.
|
||||
|
|
@ -137,20 +152,18 @@ func NewDiscovery(conf SDConfig, opts discovery.DiscovererOptions) (*Discovery,
|
|||
d := &Discovery{
|
||||
project: conf.Project,
|
||||
zone: conf.Zone,
|
||||
filter: conf.Filter,
|
||||
port: conf.Port,
|
||||
tagSeparator: conf.TagSeparator,
|
||||
}
|
||||
var err error
|
||||
d.client, err = google.DefaultClient(context.Background(), compute.ComputeReadonlyScope)
|
||||
client, err := google.DefaultClient(context.Background(), compute.ComputeReadonlyScope)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error setting up communication with GCE service: %w", err)
|
||||
}
|
||||
d.svc, err = compute.NewService(context.Background(), option.WithHTTPClient(d.client))
|
||||
svc, err := compute.NewService(context.Background(), option.WithHTTPClient(client))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error setting up communication with GCE service: %w", err)
|
||||
}
|
||||
d.isvc = compute.NewInstancesService(d.svc)
|
||||
d.listInstances = newInstancesLister(svc, conf.Project, conf.Zone, conf.Filter)
|
||||
|
||||
d.Discovery = refresh.NewDiscovery(
|
||||
refresh.Options{
|
||||
|
|
@ -170,11 +183,7 @@ func (d *Discovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) {
|
|||
Source: fmt.Sprintf("GCE_%s_%s", d.project, d.zone),
|
||||
}
|
||||
|
||||
ilc := d.isvc.List(d.project, d.zone)
|
||||
if d.filter != "" {
|
||||
ilc = ilc.Filter(d.filter)
|
||||
}
|
||||
err := ilc.Pages(ctx, func(l *compute.InstanceList) error {
|
||||
err := d.listInstances(ctx, func(l *compute.InstanceList) error {
|
||||
for _, inst := range l.Items {
|
||||
if len(inst.NetworkInterfaces) == 0 {
|
||||
continue
|
||||
|
|
|
|||
76
discovery/kubernetes/client.go
Normal file
76
discovery/kubernetes/client.go
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
// 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 kubernetes
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
appsv1client "k8s.io/client-go/kubernetes/typed/apps/v1"
|
||||
batchv1client "k8s.io/client-go/kubernetes/typed/batch/v1"
|
||||
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
discoveryv1client "k8s.io/client-go/kubernetes/typed/discovery/v1"
|
||||
networkingv1client "k8s.io/client-go/kubernetes/typed/networking/v1"
|
||||
)
|
||||
|
||||
// k8sClient exposes only the API-group accessors discovery uses. It is
|
||||
// satisfied by both clientAdapter and the fake clientset used in tests.
|
||||
type k8sClient interface {
|
||||
CoreV1() corev1client.CoreV1Interface
|
||||
AppsV1() appsv1client.AppsV1Interface
|
||||
BatchV1() batchv1client.BatchV1Interface
|
||||
DiscoveryV1() discoveryv1client.DiscoveryV1Interface
|
||||
NetworkingV1() networkingv1client.NetworkingV1Interface
|
||||
}
|
||||
|
||||
// clientAdapter captures the used API-group accessors as method-value closures.
|
||||
// Keeping the concrete clientset out of an interface-typed field avoids forcing
|
||||
// the linker, via reflection, to retain every API group and resource client,
|
||||
// which reduces the binary size.
|
||||
type clientAdapter struct {
|
||||
coreV1 func() corev1client.CoreV1Interface
|
||||
appsV1 func() appsv1client.AppsV1Interface
|
||||
batchV1 func() batchv1client.BatchV1Interface
|
||||
discoveryV1 func() discoveryv1client.DiscoveryV1Interface
|
||||
networkingV1 func() networkingv1client.NetworkingV1Interface
|
||||
}
|
||||
|
||||
// newClientAdapter wraps a concrete clientset, exposing only the API groups
|
||||
// discovery uses.
|
||||
func newClientAdapter(c *kubernetes.Clientset) *clientAdapter {
|
||||
return &clientAdapter{
|
||||
coreV1: c.CoreV1,
|
||||
appsV1: c.AppsV1,
|
||||
batchV1: c.BatchV1,
|
||||
discoveryV1: c.DiscoveryV1,
|
||||
networkingV1: c.NetworkingV1,
|
||||
}
|
||||
}
|
||||
|
||||
// CoreV1 returns the core/v1 API-group client.
|
||||
func (a *clientAdapter) CoreV1() corev1client.CoreV1Interface { return a.coreV1() }
|
||||
|
||||
// AppsV1 returns the apps/v1 API-group client.
|
||||
func (a *clientAdapter) AppsV1() appsv1client.AppsV1Interface { return a.appsV1() }
|
||||
|
||||
// BatchV1 returns the batch/v1 API-group client.
|
||||
func (a *clientAdapter) BatchV1() batchv1client.BatchV1Interface { return a.batchV1() }
|
||||
|
||||
// DiscoveryV1 returns the discovery/v1 API-group client.
|
||||
func (a *clientAdapter) DiscoveryV1() discoveryv1client.DiscoveryV1Interface {
|
||||
return a.discoveryV1()
|
||||
}
|
||||
|
||||
// NetworkingV1 returns the networking/v1 API-group client.
|
||||
func (a *clientAdapter) NetworkingV1() networkingv1client.NetworkingV1Interface {
|
||||
return a.networkingV1()
|
||||
}
|
||||
|
|
@ -254,7 +254,7 @@ func (c *NamespaceDiscovery) UnmarshalYAML(unmarshal func(any) error) error {
|
|||
// targets from Kubernetes.
|
||||
type Discovery struct {
|
||||
sync.RWMutex
|
||||
client kubernetes.Interface
|
||||
client k8sClient
|
||||
role Role
|
||||
logger *slog.Logger
|
||||
namespaceDiscovery *NamespaceDiscovery
|
||||
|
|
@ -341,7 +341,7 @@ func New(l *slog.Logger, metrics discovery.DiscovererMetrics, conf *SDConfig) (*
|
|||
}
|
||||
|
||||
d := &Discovery{
|
||||
client: c,
|
||||
client: newClientAdapter(c),
|
||||
logger: l,
|
||||
role: conf.Role,
|
||||
namespaceDiscovery: &conf.NamespaceDiscovery,
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ func testUpdateServices(client appListClient) ([]*targetgroup.Group, error) {
|
|||
}
|
||||
|
||||
func TestMarathonSDHandleError(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
errTesting = errors.New("testing failure")
|
||||
client = func(context.Context, *http.Client, string) (*appList, error) {
|
||||
|
|
@ -78,6 +79,7 @@ func TestMarathonSDHandleError(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMarathonSDEmptyList(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := func(context.Context, *http.Client, string) (*appList, error) { return &appList{}, nil }
|
||||
tgs, err := testUpdateServices(client)
|
||||
require.NoError(t, err)
|
||||
|
|
@ -111,6 +113,7 @@ func marathonTestAppList(labels map[string]string, runningTasks int) *appList {
|
|||
}
|
||||
|
||||
func TestMarathonSDSendGroup(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := func(context.Context, *http.Client, string) (*appList, error) {
|
||||
return marathonTestAppList(marathonValidLabel, 1), nil
|
||||
}
|
||||
|
|
@ -128,6 +131,7 @@ func TestMarathonSDSendGroup(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMarathonSDRemoveApp(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := testConfig()
|
||||
reg := prometheus.NewRegistry()
|
||||
refreshMetrics := discovery.NewRefreshMetrics(reg)
|
||||
|
|
@ -192,6 +196,7 @@ func marathonTestAppListWithMultiplePorts(labels map[string]string, runningTasks
|
|||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithMultiplePort(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := func(context.Context, *http.Client, string) (*appList, error) {
|
||||
return marathonTestAppListWithMultiplePorts(marathonValidLabel, 1), nil
|
||||
}
|
||||
|
|
@ -237,6 +242,7 @@ func marathonTestZeroTaskPortAppList(labels map[string]string, runningTasks int)
|
|||
}
|
||||
|
||||
func TestMarathonZeroTaskPorts(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := func(context.Context, *http.Client, string) (*appList, error) {
|
||||
return marathonTestZeroTaskPortAppList(marathonValidLabel, 1), nil
|
||||
}
|
||||
|
|
@ -250,6 +256,7 @@ func TestMarathonZeroTaskPorts(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test500ErrorHttpResponseWithValidJSONBody(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Simulate 500 error with a valid JSON response.
|
||||
respHandler := func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
|
|
@ -295,6 +302,7 @@ func marathonTestAppListWithPortDefinitions(labels map[string]string, runningTas
|
|||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithPortDefinitions(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := func(context.Context, *http.Client, string) (*appList, error) {
|
||||
return marathonTestAppListWithPortDefinitions(marathonValidLabel, 1), nil
|
||||
}
|
||||
|
|
@ -349,6 +357,7 @@ func marathonTestAppListWithPortDefinitionsRequirePorts(labels map[string]string
|
|||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithPortDefinitionsRequirePorts(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := func(context.Context, *http.Client, string) (*appList, error) {
|
||||
return marathonTestAppListWithPortDefinitionsRequirePorts(marathonValidLabel, 1), nil
|
||||
}
|
||||
|
|
@ -396,6 +405,7 @@ func marathonTestAppListWithPorts(labels map[string]string, runningTasks int) *a
|
|||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithPorts(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := func(context.Context, *http.Client, string) (*appList, error) {
|
||||
return marathonTestAppListWithPorts(marathonValidLabel, 1), nil
|
||||
}
|
||||
|
|
@ -452,6 +462,7 @@ func marathonTestAppListWithContainerPortMappings(labels map[string]string, runn
|
|||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithContainerPortMappings(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := func(context.Context, *http.Client, string) (*appList, error) {
|
||||
return marathonTestAppListWithContainerPortMappings(marathonValidLabel, 1), nil
|
||||
}
|
||||
|
|
@ -508,6 +519,7 @@ func marathonTestAppListWithDockerContainerPortMappings(labels map[string]string
|
|||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithDockerContainerPortMappings(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := func(context.Context, *http.Client, string) (*appList, error) {
|
||||
return marathonTestAppListWithDockerContainerPortMappings(marathonValidLabel, 1), nil
|
||||
}
|
||||
|
|
@ -568,6 +580,7 @@ func marathonTestAppListWithContainerNetworkAndPortMappings(labels map[string]st
|
|||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithContainerNetworkAndPortMapping(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := func(context.Context, *http.Client, string) (*appList, error) {
|
||||
return marathonTestAppListWithContainerNetworkAndPortMappings(marathonValidLabel, 1), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"github.com/prometheus/common/model"
|
||||
"github.com/prometheus/common/version"
|
||||
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
|
||||
ipam "github.com/scaleway/scaleway-sdk-go/api/ipam/v1"
|
||||
"github.com/scaleway/scaleway-sdk-go/scw"
|
||||
|
||||
"github.com/prometheus/prometheus/discovery/refresh"
|
||||
|
|
@ -104,7 +105,8 @@ func newInstanceDiscovery(conf *SDConfig) (*instanceDiscovery, error) {
|
|||
}
|
||||
|
||||
func (d *instanceDiscovery) refresh(ctx context.Context) ([]*targetgroup.Group, error) {
|
||||
api := instance.NewAPI(d.client)
|
||||
instanceAPI := instance.NewAPI(d.client)
|
||||
ipamAPI := ipam.NewAPI(d.client)
|
||||
|
||||
req := &instance.ListServersRequest{}
|
||||
|
||||
|
|
@ -116,7 +118,12 @@ func (d *instanceDiscovery) refresh(ctx context.Context) ([]*targetgroup.Group,
|
|||
req.Tags = d.tagsFilter
|
||||
}
|
||||
|
||||
servers, err := api.ListServers(req, scw.WithAllPages(), scw.WithContext(ctx))
|
||||
servers, err := instanceAPI.ListServers(req, scw.WithAllPages(), scw.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
privateNICIPByID, err := privateNICIPs(ctx, ipamAPI, servers.Servers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -208,6 +215,19 @@ func (d *instanceDiscovery) refresh(ctx context.Context) ([]*targetgroup.Group,
|
|||
addr = *server.PrivateIP
|
||||
}
|
||||
|
||||
if addr == "" {
|
||||
for _, privateNIC := range server.PrivateNics {
|
||||
if privateNIC == nil {
|
||||
continue
|
||||
}
|
||||
if privateIP := privateNICIPByID[privateNIC.ID]; privateIP != "" {
|
||||
labels[instancePrivateIPv4Label] = model.LabelValue(privateIP)
|
||||
addr = privateIP
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if addr != "" {
|
||||
addr := net.JoinHostPort(addr, strconv.FormatUint(uint64(d.port), 10))
|
||||
labels[model.AddressLabel] = model.LabelValue(addr)
|
||||
|
|
@ -217,3 +237,43 @@ func (d *instanceDiscovery) refresh(ctx context.Context) ([]*targetgroup.Group,
|
|||
|
||||
return []*targetgroup.Group{{Source: "scaleway", Targets: targets}}, nil
|
||||
}
|
||||
|
||||
func privateNICIPs(ctx context.Context, api *ipam.API, servers []*instance.Server) (map[string]string, error) {
|
||||
privateNICIDsByRegion := map[scw.Region][]string{}
|
||||
for _, server := range servers {
|
||||
if server.PrivateIP != nil || server.PublicIP != nil || server.IPv6 != nil { //nolint:staticcheck
|
||||
continue
|
||||
}
|
||||
|
||||
region, err := server.Zone.Region()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, privateNIC := range server.PrivateNics {
|
||||
if privateNIC != nil && privateNIC.ID != "" {
|
||||
privateNICIDsByRegion[region] = append(privateNICIDsByRegion[region], privateNIC.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
privateNICIPs := map[string]string{}
|
||||
for region, privateNICIDs := range privateNICIDsByRegion {
|
||||
ips, err := api.ListIPs(&ipam.ListIPsRequest{
|
||||
Region: region,
|
||||
ResourceIDs: privateNICIDs,
|
||||
ResourceTypes: []ipam.ResourceType{ipam.ResourceTypeInstancePrivateNic},
|
||||
}, scw.WithAllPages(), scw.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, ip := range ips.IPs {
|
||||
if ip != nil && ip.Resource != nil && !ip.IsIPv6 && ip.Address.IP != nil {
|
||||
privateNICIPs[ip.Resource.ID] = ip.Address.IP.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return privateNICIPs, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,6 +187,95 @@ func mockScalewayInstance(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestScalewayInstanceRefreshIPAMPrivateNIC(t *testing.T) {
|
||||
mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Header.Get("X-Auth-Token") != testSecretKey {
|
||||
http.Error(w, "bad token id", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
switch r.URL.Path {
|
||||
case "/instance/v1/zones/fr-par-1/servers":
|
||||
_, err := w.Write([]byte(`{
|
||||
"servers": [
|
||||
{
|
||||
"id": "78d6aa69-6a5f-47bd-9f1a-3cdde6973d96",
|
||||
"name": "ipam-only",
|
||||
"organization": "cb334986-b054-4725-9d3a-40850fdc6015",
|
||||
"project": "cb334986-b054-4725-9d5a-30850fdc6015",
|
||||
"commercial_type": "DEV1-S",
|
||||
"hostname": "ipam-only",
|
||||
"state": "running",
|
||||
"boot_type": "local",
|
||||
"routed_ip_enabled": true,
|
||||
"public_ip": null,
|
||||
"public_ips": [],
|
||||
"private_ip": null,
|
||||
"private_nics": [
|
||||
{
|
||||
"id": "2d17a5a0-f8e5-4e7f-a029-f7c8d182af53",
|
||||
"server_id": "78d6aa69-6a5f-47bd-9f1a-3cdde6973d96",
|
||||
"private_network_id": "18ba4ed4-d194-4b5d-9083-447325234a71",
|
||||
"mac_address": "02:00:00:00:31:90",
|
||||
"state": "available",
|
||||
"zone": "fr-par-1"
|
||||
}
|
||||
],
|
||||
"zone": "fr-par-1"
|
||||
}
|
||||
]
|
||||
}`))
|
||||
require.NoError(t, err)
|
||||
case "/ipam/v1/regions/fr-par/ips":
|
||||
require.Equal(t, "2d17a5a0-f8e5-4e7f-a029-f7c8d182af53", r.URL.Query().Get("resource_ids"))
|
||||
require.Equal(t, "instance_private_nic", r.URL.Query().Get("resource_types"))
|
||||
_, err := w.Write([]byte(`{
|
||||
"ips": [
|
||||
{
|
||||
"id": "b50244c4-b0b1-4cc9-a78c-26034b4967d3",
|
||||
"address": "10.0.0.7/32",
|
||||
"project_id": "cb334986-b054-4725-9d5a-30850fdc6015",
|
||||
"is_ipv6": false,
|
||||
"resource": {
|
||||
"type": "instance_private_nic",
|
||||
"id": "2d17a5a0-f8e5-4e7f-a029-f7c8d182af53"
|
||||
},
|
||||
"region": "fr-par"
|
||||
}
|
||||
],
|
||||
"total_count": 1
|
||||
}`))
|
||||
require.NoError(t, err)
|
||||
default:
|
||||
http.Error(w, "bad url", http.StatusNotFound)
|
||||
}
|
||||
}))
|
||||
defer mock.Close()
|
||||
|
||||
cfgString := fmt.Sprintf(`
|
||||
---
|
||||
role: instance
|
||||
project_id: %s
|
||||
secret_key: %s
|
||||
access_key: %s
|
||||
api_url: %s
|
||||
`, testProjectID, testSecretKey, testAccessKey, mock.URL)
|
||||
var cfg SDConfig
|
||||
require.NoError(t, yaml.UnmarshalStrict([]byte(cfgString), &cfg))
|
||||
|
||||
d, err := newRefresher(&cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
tgs, err := d.refresh(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, tgs, 1)
|
||||
require.Len(t, tgs[0].Targets, 1)
|
||||
require.Equal(t, model.LabelValue("10.0.0.7:80"), tgs[0].Targets[0][model.AddressLabel])
|
||||
require.Equal(t, model.LabelValue("10.0.0.7"), tgs[0].Targets[0][instancePrivateIPv4Label])
|
||||
}
|
||||
|
||||
func TestScalewayInstanceAuthToken(t *testing.T) {
|
||||
mock := httptest.NewServer(http.HandlerFunc(mockScalewayInstance))
|
||||
defer mock.Close()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}(),
|
||||
|
|
|
|||
|
|
@ -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"`
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ The Prometheus monitoring server
|
|||
| <code class="text-nowrap">-h</code>, <code class="text-nowrap">--help</code> | Show context-sensitive help (also try --help-long and --help-man). | |
|
||||
| <code class="text-nowrap">--version</code> | Show application version. | |
|
||||
| <code class="text-nowrap">--config.file</code> | Prometheus configuration file path. | `prometheus.yml` |
|
||||
| <code class="text-nowrap">--config.auto-reload-interval</code> | Specifies the interval for checking and automatically reloading the Prometheus configuration file upon detecting changes. | `30s` |
|
||||
| <code class="text-nowrap">--web.listen-address</code> <code class="text-nowrap">...<code class="text-nowrap"> | Address to listen on for UI, API, and telemetry. Can be repeated. | `0.0.0.0:9090` |
|
||||
| <code class="text-nowrap">--config.auto-reload</code> | Enable automatic configuration file reloading. See also --config.auto-reload-interval. | `false` |
|
||||
| <code class="text-nowrap">--config.auto-reload-interval</code> | Specifies the interval for checking and automatically reloading the Prometheus configuration file upon detecting changes. Only used when --config.auto-reload is set. | `30s` |
|
||||
| <code class="text-nowrap">--web.listen-address</code> <code class="text-nowrap">...</code> | Address to listen on for UI, API, and telemetry. Can be repeated. | `0.0.0.0:9090` |
|
||||
| <code class="text-nowrap">--auto-gomaxprocs</code> | Automatically set GOMAXPROCS to match Linux container CPU quota | `true` |
|
||||
| <code class="text-nowrap">--auto-gomemlimit</code> | Automatically set GOMEMLIMIT to match Linux container or system memory limit | `true` |
|
||||
| <code class="text-nowrap">--auto-gomemlimit.ratio</code> | The ratio of reserved GOMEMLIMIT memory to the detected maximum container or system memory | `0.9` |
|
||||
|
|
@ -50,6 +51,7 @@ The Prometheus monitoring server
|
|||
| <code class="text-nowrap">--storage.remote.read-sample-limit</code> | Maximum overall number of samples to return via the remote read interface, in a single query. 0 means no limit. This limit is ignored for streamed response types. Use with server mode only. | `5e7` |
|
||||
| <code class="text-nowrap">--storage.remote.read-concurrent-limit</code> | Maximum number of concurrent remote read calls. 0 means no limit. Use with server mode only. | `10` |
|
||||
| <code class="text-nowrap">--storage.remote.read-max-bytes-in-frame</code> | Maximum number of bytes in a single frame for streaming remote read response types before marshalling. Note that client might have limit on frame size as well. 1MB as recommended by protobuf by default. Use with server mode only. | `1048576` |
|
||||
| <code class="text-nowrap">--web.search.max-limit</code> | Hard upper bound on the "limit" query parameter accepted by the experimental search API (--enable-feature=search-api). Requests with a higher limit are rejected with HTTP 400. 0 disables the cap. Use with server mode only. | `10000` |
|
||||
| <code class="text-nowrap">--rules.alert.for-outage-tolerance</code> | Max time to tolerate prometheus outage for restoring "for" state of alert. Use with server mode only. | `1h` |
|
||||
| <code class="text-nowrap">--rules.alert.for-grace-period</code> | Minimum duration between alert and restored "for" state. This is maintained only for alerts with configured "for" time greater than grace period. Use with server mode only. | `10m` |
|
||||
| <code class="text-nowrap">--rules.alert.resend-delay</code> | Minimum amount of time to wait before resending an alert to Alertmanager. Use with server mode only. | `1m` |
|
||||
|
|
@ -61,7 +63,7 @@ The Prometheus monitoring server
|
|||
| <code class="text-nowrap">--query.timeout</code> | Maximum time a query may take before being aborted. Use with server mode only. | `2m` |
|
||||
| <code class="text-nowrap">--query.max-concurrency</code> | Maximum number of queries executed concurrently. Use with server mode only. | `20` |
|
||||
| <code class="text-nowrap">--query.max-samples</code> | 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` |
|
||||
| <code class="text-nowrap">--enable-feature</code> <code class="text-nowrap">...<code class="text-nowrap"> | 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. | |
|
||||
| <code class="text-nowrap">--enable-feature</code> <code class="text-nowrap">...</code> | 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, search-api, st-storage, st-synthesis, type-and-unit-labels, use-start-timestamps, use-uncached-io, xor2-encoding. See https://prometheus.io/docs/prometheus/latest/feature_flags/ for more details. | |
|
||||
| <code class="text-nowrap">--agent</code> | Run Prometheus in 'Agent mode'. | |
|
||||
| <code class="text-nowrap">--log.level</code> | Only log messages with the given severity or above. One of: [debug, info, warn, error] | `info` |
|
||||
| <code class="text-nowrap">--log.format</code> | Output format of log messages. One of: [logfmt, json] | `logfmt` |
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ Tooling for the Prometheus monitoring system.
|
|||
| <code class="text-nowrap">-h</code>, <code class="text-nowrap">--help</code> | Show context-sensitive help (also try --help-long and --help-man). |
|
||||
| <code class="text-nowrap">--version</code> | Show application version. |
|
||||
| <code class="text-nowrap">--experimental</code> | Enable experimental commands. |
|
||||
| <code class="text-nowrap">--enable-feature</code> <code class="text-nowrap">...<code class="text-nowrap"> | 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 |
|
||||
| <code class="text-nowrap">--enable-feature</code> <code class="text-nowrap">...</code> | 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 |
|
||||
|
||||
|
||||
|
||||
|
|
@ -293,7 +293,7 @@ Run series query.
|
|||
|
||||
| Flag | Description |
|
||||
| --- | --- |
|
||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...<code class="text-nowrap"> | Series selector. Can be specified multiple times. |
|
||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...</code> | Series selector. Can be specified multiple times. |
|
||||
| <code class="text-nowrap">--start</code> | Start time (RFC3339 or Unix timestamp). |
|
||||
| <code class="text-nowrap">--end</code> | End time (RFC3339 or Unix timestamp). |
|
||||
|
||||
|
|
@ -321,7 +321,7 @@ Run labels query.
|
|||
| --- | --- |
|
||||
| <code class="text-nowrap">--start</code> | Start time (RFC3339 or Unix timestamp). |
|
||||
| <code class="text-nowrap">--end</code> | End time (RFC3339 or Unix timestamp). |
|
||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...<code class="text-nowrap"> | Series selector. Can be specified multiple times. |
|
||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...</code> | Series selector. Can be specified multiple times. |
|
||||
|
||||
|
||||
|
||||
|
|
@ -350,7 +350,7 @@ Run queries against your Prometheus to analyze the usage pattern of certain metr
|
|||
| <code class="text-nowrap">--type</code> | Type of metric: histogram. | |
|
||||
| <code class="text-nowrap">--duration</code> | Time frame to analyze. | `1h` |
|
||||
| <code class="text-nowrap">--time</code> | Query time (RFC3339 or Unix timestamp), defaults to now. | |
|
||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...<code class="text-nowrap"> | Series selector. Can be specified multiple times. | |
|
||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...</code> | Series selector. Can be specified multiple times. | |
|
||||
|
||||
|
||||
|
||||
|
|
@ -474,7 +474,7 @@ Unit tests for rules.
|
|||
|
||||
| Flag | Description | Default |
|
||||
| --- | --- | --- |
|
||||
| <code class="text-nowrap">--run</code> <code class="text-nowrap">...<code class="text-nowrap"> | If set, will only run test groups whose names match the regular expression. Can be specified multiple times. | |
|
||||
| <code class="text-nowrap">--run</code> <code class="text-nowrap">...</code> | If set, will only run test groups whose names match the regular expression. Can be specified multiple times. | |
|
||||
| <code class="text-nowrap">--debug</code> | Enable unit test debugging. | `false` |
|
||||
| <code class="text-nowrap">--diff</code> | [Experimental] Print colored differential output between expected & received output. | `false` |
|
||||
| <code class="text-nowrap">--ignore-unknown-fields</code> | Ignore unknown fields in the test files. This is useful when you want to extend rule files with custom metadata. Ensure that those fields are removed before loading them into the Prometheus server as it performs strict checks by default. | `false` |
|
||||
|
|
@ -593,7 +593,7 @@ Dump data (series+samples or optionally just series) from a TSDB.
|
|||
| <code class="text-nowrap">--sandbox-dir-root</code> | Root directory where a sandbox directory will be created, this sandbox is used in case WAL replay generates chunks (default is the database path). The sandbox is cleaned up at the end. | |
|
||||
| <code class="text-nowrap">--min-time</code> | Minimum timestamp to dump, in milliseconds since the Unix epoch. | `-9223372036854775808` |
|
||||
| <code class="text-nowrap">--max-time</code> | Maximum timestamp to dump, in milliseconds since the Unix epoch. | `9223372036854775807` |
|
||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...<code class="text-nowrap"> | Series selector. Can be specified multiple times. | `{__name__=~'(?s:.*)'}` |
|
||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...</code> | Series selector. Can be specified multiple times. | `{__name__=~'(?s:.*)'}` |
|
||||
| <code class="text-nowrap">--format</code> | Output format of the dump (prom (default) or seriesjson). | `prom` |
|
||||
|
||||
|
||||
|
|
@ -621,7 +621,7 @@ Dump data (series+samples or optionally just series) from a TSDB.
|
|||
| <code class="text-nowrap">--sandbox-dir-root</code> | Root directory where a sandbox directory will be created, this sandbox is used in case WAL replay generates chunks (default is the database path). The sandbox is cleaned up at the end. | |
|
||||
| <code class="text-nowrap">--min-time</code> | Minimum timestamp to dump, in milliseconds since the Unix epoch. | `-9223372036854775808` |
|
||||
| <code class="text-nowrap">--max-time</code> | Maximum timestamp to dump, in milliseconds since the Unix epoch. | `9223372036854775807` |
|
||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...<code class="text-nowrap"> | Series selector. Can be specified multiple times. | `{__name__=~'(?s:.*)'}` |
|
||||
| <code class="text-nowrap">--match</code> <code class="text-nowrap">...</code> | Series selector. Can be specified multiple times. | `{__name__=~'(?s:.*)'}` |
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -3425,7 +3427,8 @@ Initially, aside from the configured per-target labels, a target's `job`
|
|||
label is set to the `job_name` value of the respective scrape configuration.
|
||||
|
||||
You can also use special labels like `__address__`, `__scheme__`, `__metrics_path__`,
|
||||
`__scrape_interval__`, `__scrape_timeout__` to customize the defined targets. These will
|
||||
`__scrape_interval__`, `__scrape_timeout__`, `__convert_classic_histograms_to_nhcb__`
|
||||
to customize the defined targets. These will
|
||||
override the respective settings in the scrape configuration.
|
||||
|
||||
The `__address__` label is set to the `<host>:<port>` address of the target.
|
||||
|
|
@ -3441,6 +3444,13 @@ label is set to the value of the first passed URL parameter called `<name>`, as
|
|||
The `__scrape_interval__` and `__scrape_timeout__` labels are set to the target's
|
||||
interval and timeout, as specified in `scrape_config`.
|
||||
|
||||
The `__convert_classic_histograms_to_nhcb__` label is set to the target's
|
||||
`convert_classic_histograms_to_nhcb` value, as specified in `scrape_config`
|
||||
(defaulting to the configured global). Setting it during relabeling overrides,
|
||||
per target, whether classic histograms are converted to native histograms with
|
||||
custom buckets. Its value must parse as a boolean; a target with an invalid
|
||||
value is dropped.
|
||||
|
||||
Additional labels prefixed with `__meta_` may be available during the
|
||||
relabeling phase. They are set by the service discovery mechanism that provided
|
||||
the target and vary between mechanisms.
|
||||
|
|
|
|||
|
|
@ -107,6 +107,19 @@ Besides enabling this feature in Prometheus, start timestamps need to be exposed
|
|||
|
||||
Enables the use of start timestamps (ST) in PromQL functions such as `rate()`, `irate()`, and `increase()`. This feature doesn't currently work with extended range selectors (`promql-extended-range-selectors`).
|
||||
|
||||
## Start timestamp (ST) synthesis
|
||||
|
||||
`--enable-feature=st-synthesis`
|
||||
|
||||
Enables the synthesis of start timestamps (ST) for cumulative metrics (Counters, Classic Histograms, Native Histograms) when they are not provided by the source. Similar to [the official OpenTelemetry metricstarttimeprocessor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/metricstarttimeprocessor#strategy-subtract-initial-point), it tracks previous values to detect resets and subtracts the initial reference point to synthesize a zero-based timeline from the first sample.
|
||||
|
||||
> NOTE: This is an experimental feature.
|
||||
> * The first sample is dropped when this feature is turned on to establish the start timestamp reference point. As a result, if a series has only a single point reported, turning this feature on may result in no points being ingested for that series.
|
||||
> * Synthesis yields accurate Start Timestamp while maintaining accurate counter rates. However, the raw counter values will be different that what's scraped. This is because the first point is dropped and its timestamp is used as the start timestamp for all subsequent points. All subsequent points are normalized against that dropped point (i.e. subtracted by it). Effectively, synthesis create new counter streams with the known start timestamp from the original data.
|
||||
> * Synthesis works only with scraped data (RW and Otel receiver are not implemented).
|
||||
> * Synthesis requires ordered samples. As a result, cumulative samples without ST that are out of order will be rejected despite the `tsdb. out_of_order_time_window` setting.
|
||||
> * If an append fails for a series (e.g., due to out-of-order samples being rejected), the synthesis state for that series is cleared. As a result, the next sample received after the failure will be treated as the first sample again and will be dropped to establish a new reference point.
|
||||
|
||||
## Concurrent evaluation of independent rules
|
||||
|
||||
`--enable-feature=concurrent-rule-eval`
|
||||
|
|
@ -170,19 +183,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`
|
||||
|
|
@ -205,6 +205,66 @@ 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_of(<duration>, <duration>)` and `max_of(<duration>, <duration>)` select between two duration expressions.
|
||||
`min_of` returns the smaller of the two, which is useful for capping a duration at a maximum value.
|
||||
`max_of` returns the larger of the two, which is useful for enforcing a minimum value.
|
||||
For example, `max_of(step(), 5s)` ensures the duration is never shorter than `5s`, while `min_of(range(), 1h)` caps the duration at `1h`.
|
||||
|
||||
**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_of(step(), 5s)` is equivalent to the larger of the query step width and `5s`.
|
||||
* `min_of(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`
|
||||
|
|
@ -344,3 +404,21 @@ Example query:
|
|||
```
|
||||
|
||||
See [the fill modifiers documentation](querying/operators.md#filling-in-missing-matches) for more details and examples.
|
||||
|
||||
|
||||
## Search API
|
||||
|
||||
`--enable-feature=search-api`
|
||||
|
||||
Enables the experimental search API endpoints for discovering metric names,
|
||||
label names, and label values with fuzzy matching and filtering support. See
|
||||
[the search API documentation](querying/api.md#searching-metric-names-label-names-and-label-values)
|
||||
for details.
|
||||
|
||||
The `--web.search.max-limit` flag (default `10000`) bounds the `limit` query
|
||||
parameter accepted by the search endpoints. Requests with a higher `limit` are
|
||||
rejected with HTTP 400. The default response limit (100) is silently clamped
|
||||
to this maximum, so an operator setting a smaller cap does not break
|
||||
no-`limit` requests. Setting the flag to `0` disables the cap entirely; this
|
||||
is **not recommended** for endpoints exposed beyond a trusted network because a
|
||||
single client can then request the entire index in one response.
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ URL query parameters:
|
|||
- `timeout=<duration>`: Evaluation timeout. Optional. Defaults to and
|
||||
is capped by the value of the `-query.timeout` flag.
|
||||
- `limit=<number>`: Maximum number of returned series. Doesn't affect scalars or strings but truncates the number of series for matrices and vectors. Optional. 0 means disabled.
|
||||
- `lookback_delta=<duration | float>`: Override the the [lookback period](#staleness) just for this query in `duration` format or float number of seconds. Optional.
|
||||
- `lookback_delta=<duration | float>`: Override the [lookback period](#staleness) just for this query in `duration` format or float number of seconds. Optional.
|
||||
- `stats=<string>`: Include query statistics in the response. If set to `all`, includes detailed statistics. Optional.
|
||||
|
||||
The current server time is used if the `time` parameter is omitted.
|
||||
|
|
@ -175,7 +175,7 @@ URL query parameters:
|
|||
- `timeout=<duration>`: Evaluation timeout. Optional. Defaults to and
|
||||
is capped by the value of the `-query.timeout` flag.
|
||||
- `limit=<number>`: Maximum number of returned series. Optional. 0 means disabled.
|
||||
- `lookback_delta=<duration | float>`: Override the the [lookback period](#staleness) just for this query in `duration` format or float number of seconds. Optional.
|
||||
- `lookback_delta=<duration | float>`: Override the [lookback period](#staleness) just for this query in `duration` format or float number of seconds. Optional.
|
||||
- `stats=<string>`: Include query statistics in the response. If set to `all`, includes detailed statistics. Optional.
|
||||
|
||||
You can URL-encode these parameters directly in the request body by using the `POST` method and
|
||||
|
|
@ -521,6 +521,114 @@ curl http://localhost:9090/api/v1/label/U__http_2e_status_code/values
|
|||
}
|
||||
```
|
||||
|
||||
### Searching metric names, label names, and label values
|
||||
|
||||
These endpoints are experimental and must be enabled with
|
||||
`--enable-feature=search-api`.
|
||||
|
||||
The following endpoints provide streamed discovery results for metric names,
|
||||
label names, and label values:
|
||||
|
||||
```
|
||||
GET /api/v1/search/metric_names
|
||||
POST /api/v1/search/metric_names
|
||||
GET /api/v1/search/label_names
|
||||
POST /api/v1/search/label_names
|
||||
GET /api/v1/search/label_values
|
||||
POST /api/v1/search/label_values
|
||||
```
|
||||
|
||||
These endpoints return newline-delimited JSON with content type
|
||||
`application/x-ndjson`. The stream contract is:
|
||||
|
||||
- Zero or more **batch lines**, each with a `results` array and an optional
|
||||
`warnings` array.
|
||||
- The stream then ends with **either** a **trailer line** (`status`, `has_more`,
|
||||
optional `warnings`) **or** an **error line** (`status`, `errorType`, `error`)
|
||||
if iteration failed mid-stream after the first batch was sent.
|
||||
|
||||
```json
|
||||
{"results":[{"name":"http_requests_total","type":"counter","help":"Total HTTP requests."}]}
|
||||
{"status":"success","has_more":false}
|
||||
```
|
||||
|
||||
If an error occurs **before** streaming starts, the API returns the usual
|
||||
Prometheus JSON error object with a 4xx/5xx status code. If an error occurs
|
||||
**after** streaming starts, the stream ends with an NDJSON error line in place
|
||||
of the trailer.
|
||||
|
||||
Clients must tolerate an abrupt EOF without a trailer (for example, on
|
||||
transport failure or server shutdown) and must ignore unknown fields in the
|
||||
trailer for forward compatibility.
|
||||
|
||||
The `has_more` field in the trailer is informational only: this version of
|
||||
the API does not provide a pagination cursor. To retrieve more results, raise
|
||||
`limit` (subject to the operator-configured `--web.search.max-limit`) or narrow
|
||||
the request via `match[]`. A future version of the API may add a cursor.
|
||||
|
||||
Common URL query parameters:
|
||||
|
||||
- `match[]=<series_selector>`: Repeated series selector used to scope the
|
||||
search. Optional.
|
||||
- `search[]=<string>`: Repeated search string matched against names or values.
|
||||
Multiple values use OR semantics. Optional.
|
||||
- `fuzz_threshold=<number>`: Fuzzy threshold from 0 to 100. Optional. A value
|
||||
of 0 is the lowest fuzzy threshold.
|
||||
- `fuzz_alg=<subsequence | jarowinkler>`: Matching algorithm. Optional. Default
|
||||
is `subsequence`.
|
||||
- `case_sensitive=<bool>`: Toggle case-sensitive matching. Optional.
|
||||
- `sort_by=<string>`: Sort mode. Supported values depend on the endpoint.
|
||||
- `sort_dir=<asc | dsc>`: Sort direction. Optional. Only valid with
|
||||
`sort_by=alpha`.
|
||||
- `include_score=<bool>`: Include the relevance score in each result. Optional.
|
||||
- `start=<rfc3339 | unix_timestamp>`: Start timestamp. Optional.
|
||||
- `end=<rfc3339 | unix_timestamp>`: End timestamp. Optional.
|
||||
- `limit=<number>`: Maximum number of returned results. Optional. Default is
|
||||
100.
|
||||
- `batch_size=<number>`: Preferred number of results per NDJSON batch.
|
||||
Optional. Default is 100.
|
||||
|
||||
The `start` and `end` parameters narrow results to the selected time window.
|
||||
Results may include values from series active slightly outside that window,
|
||||
because Prometheus stores data in fixed-size blocks (typically 2 hours each).
|
||||
|
||||
Additional parameters for `/api/v1/search/metric_names`:
|
||||
|
||||
- `include_metadata=<bool>`: Include metric metadata in each result.
|
||||
- `sort_by=<alpha | score>`
|
||||
|
||||
Additional parameters for `/api/v1/search/label_names`:
|
||||
|
||||
- `sort_by=<alpha | score>`
|
||||
|
||||
Additional parameters for `/api/v1/search/label_values`:
|
||||
|
||||
- `label=<label_name>`: Label name whose values should be searched. Required.
|
||||
- `sort_by=<alpha | score>`
|
||||
|
||||
This example searches metric names for autocomplete:
|
||||
|
||||
```bash
|
||||
curl -g 'http://localhost:9090/api/v1/search/metric_names?search[]=http_req&sort_by=score&include_metadata=true&limit=5'
|
||||
```
|
||||
|
||||
```json
|
||||
{"results":[{"name":"http_requests_total","type":"counter","help":"Total HTTP requests."}]}
|
||||
{"status":"success","has_more":false}
|
||||
```
|
||||
|
||||
This example searches label values for the `instance` label within the `up`
|
||||
metric:
|
||||
|
||||
```bash
|
||||
curl -g 'http://localhost:9090/api/v1/search/label_values?label=instance&match[]=up&search[]=909&sort_by=score'
|
||||
```
|
||||
|
||||
```json
|
||||
{"results":[{"value":"localhost:9090"},{"value":"localhost:9091"}]}
|
||||
{"status":"success","has_more":true}
|
||||
```
|
||||
|
||||
## Querying exemplars
|
||||
|
||||
This is **experimental** and might change in the future.
|
||||
|
|
@ -766,6 +874,7 @@ curl http://localhost:9090/api/v1/targets
|
|||
{
|
||||
"discoveredLabels": {
|
||||
"__address__": "127.0.0.1:9100",
|
||||
"__convert_classic_histograms_to_nhcb__": "false",
|
||||
"__metrics_path__": "/metrics",
|
||||
"__scheme__": "http",
|
||||
"__scrape_interval__": "1m",
|
||||
|
|
|
|||
|
|
@ -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(<duration>, <duration>)` and `max(<duration>, <duration>)` 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: `<instant_query> '[' <range> ':' [<resolution>] ']' [ @ <float_literal> ] [ offset <duration> ]`
|
||||
Syntax: `<instant_query> '[' <range> ':' [<resolution>] ']' [ @ <float_literal> ] [ offset <float_literal> ]`
|
||||
|
||||
* `<range>`, `<resolution>`, and `offset` support duration expressions.
|
||||
* `<resolution>` is optional. Default is the global evaluation interval.
|
||||
|
||||
## Operators
|
||||
|
|
|
|||
|
|
@ -693,6 +693,24 @@ This second example has the same effect than the first example, and illustrates
|
|||
label_replace(up{job="api-server",service="a:c"}, "foo", "$name", "service", "(?P<name>.*):(?P<version>.*)")
|
||||
```
|
||||
|
||||
## `max_of()`
|
||||
|
||||
**This function has to be enabled via the [feature
|
||||
flag](../feature_flags.md#experimental-promql-functions)
|
||||
`--enable-feature=promql-experimental-functions`.**
|
||||
|
||||
`max_of(a scalar, b scalar)` returns the larger of the two scalar values `a`
|
||||
and `b`.
|
||||
|
||||
## `min_of()`
|
||||
|
||||
**This function has to be enabled via the [feature
|
||||
flag](../feature_flags.md#experimental-promql-functions)
|
||||
`--enable-feature=promql-experimental-functions`.**
|
||||
|
||||
`min_of(a scalar, b scalar)` returns the smaller of the two scalar values `a`
|
||||
and `b`.
|
||||
|
||||
## `ln()`
|
||||
|
||||
`ln(v instant-vector)` calculates the natural logarithm for all float samples
|
||||
|
|
@ -961,7 +979,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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.17 // 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.304.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.81.0 // 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.54.0 // 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.36.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 // indirect
|
||||
github.com/aws/smithy-go v1.26.0 // 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.193.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-20260528135333-5b027732945f // indirect
|
||||
github.com/hetznercloud/hcloud-go/v2 v2.41.2 // 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.1 // 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,54 @@ 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.153.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.153.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.153.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-20260518105423-c9d5bc4c50a9 // 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.59.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap v1.59.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.153.0 // indirect
|
||||
go.opentelemetry.io/collector/consumer v1.59.0 // indirect
|
||||
go.opentelemetry.io/collector/featuregate v1.59.0 // indirect
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.153.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata v1.59.0 // indirect
|
||||
go.opentelemetry.io/collector/pipeline v1.59.0 // indirect
|
||||
go.opentelemetry.io/collector/processor v1.59.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.69.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 // indirect
|
||||
go.opentelemetry.io/otel v1.44.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.44.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.44.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.51.0 // indirect
|
||||
golang.org/x/mod v0.36.0 // indirect
|
||||
golang.org/x/net v0.55.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.45.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-20260526163538-3dc84a4a5aaa // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
|
||||
google.golang.org/grpc v1.81.1 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apimachinery v0.35.3 // indirect
|
||||
|
|
|
|||
|
|
@ -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.18 h1:Hcia46bxhGgF3BaSnG8nSNCWmqTK6bj9xN9/FJ3WK6Q=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.18/go.mod h1:zEjCAYmxqDadH1WX8CdBvmLKhUEUVFgKRQG38zjDmrY=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.17 h1:gP2nkGsS+KMvF/jfFz2Vv2qiiOqWKyPACSzPsqHgoW8=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.17/go.mod h1:Bsew3S/moG5iT77giPj1q8wb/s0RE5/QfH+ASjYtuQc=
|
||||
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.304.0 h1:wZthLlYdKxBo7NpWLbl0A/8DB/QNDB+8RJa9WboK9Q0=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.304.0/go.mod h1:Y95W0Hm6FYLPa6o0hbnJ+sWgmdc4ifcLFjGkdobWVhY=
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.81.0 h1:2Sp9EwK7giQpJnQ54k0zdUh6aykmmbpEurEEygr104c=
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.81.0/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.54.0 h1:07DKnL5eKSel3XEM2UxlD/z9zUZZ6XMHLGDXkAdY4u8=
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.54.0/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.36.0 h1:nDARhv/oF55bcxF7rCI/4PDxOKnVXVWwDuDwCs2I2SQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.0/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.26.0 h1:9ouqbi+NyKP7fV3Te7UElCwdAb6Y8uk7LGwPE5tVe/s=
|
||||
github.com/aws/smithy-go v1.26.0/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.193.0 h1:CSbbUl5LufT75KPNvex3vDnBYjY2RfJWs7T3Ac7dHpA=
|
||||
github.com/digitalocean/godo v1.193.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-20260528135333-5b027732945f h1:sdf4a6FF3tC1/c0buuizLAwZa/xLu4gWD87qWrzQLvo=
|
||||
github.com/hashicorp/nomad/api v0.0.0-20260528135333-5b027732945f/go.mod h1:Kr8imJwigbQ/50BqVae2+JL+AyX+FnzbnuCoIFb6iYg=
|
||||
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.41.2 h1:fO5zsMgp5oejrtnFj8mYuqlp+iMuirpaKv4b5FYNRdQ=
|
||||
github.com/hetznercloud/hcloud-go/v2 v2.41.2/go.mod h1:9OGvC//jbHE4sv2Oyo0bQ2vEWuUMKYoNMyj9Qxz2qcc=
|
||||
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.1 h1:f45N2MHR/oece2/ktTTCYmrlfse4//k3NgwcF5zbGZ0=
|
||||
github.com/linode/linodego v1.69.1/go.mod h1:Fha0NYsQSx5VZK1HQNJY/z/dIxxkFp+vb5veawbmAUw=
|
||||
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.153.0 h1:hrLQLVZ4YXs35G9QvPO+xcu6qMnUpCt3WOpBDM7dR+E=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.153.0/go.mod h1:+qlIXDaBLIX+egj/okymUG88KSdAD8nIEHY8+tXt8+M=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.153.0 h1:kPPv0sQQH2R2CitTPYXDfq1z1ekStnmk39C8RkOrsbI=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.153.0/go.mod h1:wFACQmv2KfJyvyiRtMrI/DmcOWKEk6SxY0nLduWFMC4=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.153.0 h1:3MR2JvG1KB4GUiMi5asE6K0Ln5cjWPEfVAIpUwf55Sk=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.153.0/go.mod h1:0lEaZGCEjzb4R5J6F0NR1jF1KKc18IkvPRwLpQuyyjY=
|
||||
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-20260518105423-c9d5bc4c50a9 h1:e33IfrrwrJkylWwAGcQ2jMvbWVv13lv0suTXjGNeiqY=
|
||||
github.com/prometheus/client_golang/exp v0.0.0-20260518105423-c9d5bc4c50a9/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.59.0 h1:WtulkwzsdAOM/LE0cH/IiudUgiyb2ueVDDeEh5HsXzo=
|
||||
go.opentelemetry.io/collector/component v1.59.0/go.mod h1:5eQCM0tS6qbG2XJ6Bt67kgCxuhCbg4csVv6SywyHZ6w=
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.153.0 h1:bZu1Qs1eHw5ZY2UEKq0f5IcctDgc6zjUYwCE1T22Tmw=
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.153.0/go.mod h1:SfYWwh6pA9jJUcjuX+zIJ9kyn+2Z9SSLMM3xYOBsVW4=
|
||||
go.opentelemetry.io/collector/component/componenttest v0.153.0 h1:u6O1l+9PUNnI22k8q4sF9wgLAUyt+y2Ov7xi1yZ+wE4=
|
||||
go.opentelemetry.io/collector/component/componenttest v0.153.0/go.mod h1:Ym/d5UxnoHmrCI5LsVANBicikNiqtwjk8uWBM+Z4jDM=
|
||||
go.opentelemetry.io/collector/confmap v1.59.0 h1:asxEEiWwNuGfmTVSctYArOTF8jcxYpS4NmPtvvFhNNI=
|
||||
go.opentelemetry.io/collector/confmap v1.59.0/go.mod h1:X5SjFINrF0cb0hcM8PwnW2z+0L/pHA1H1yPPtm2j0tY=
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.153.0 h1:RSn7C87eBp1iuWip3hX8v9AR8adMze1usJxwumefkq4=
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.153.0/go.mod h1:4SuPyutUiirRqQoPeY+13lLYkOQ2opMQgKvKACnXh1k=
|
||||
go.opentelemetry.io/collector/consumer v1.59.0 h1:EFDQ8ZTWwHEratWusKgW26W20LeAWdXj235iD9MxpuA=
|
||||
go.opentelemetry.io/collector/consumer v1.59.0/go.mod h1:wrOSfXkKjzEeHYxhKGukuB9+NFV/CboWwEH1oEXhMtw=
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.153.0 h1:fCqkOWNVK/qipg4SX60zICs3jhKDjcrtF1oxJR6msCk=
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.153.0/go.mod h1:YfVqyCrvEfvsbbrpfiH97fITh4vmIBzZT112tUluqx0=
|
||||
go.opentelemetry.io/collector/consumer/xconsumer v0.153.0 h1:Jt1Aiiq9zDILzppRTEdZXaA830KBjjP1i2kWL+h5br0=
|
||||
go.opentelemetry.io/collector/consumer/xconsumer v0.153.0/go.mod h1:IzJ/dTOtEUMjY0DYu6kO946u5jbiDDUG8+sLaLhJ+HY=
|
||||
go.opentelemetry.io/collector/featuregate v1.59.0 h1:pu70/9eWRjAjzGnr3VmqwY+k6fmU3esLp15AqxfBBz0=
|
||||
go.opentelemetry.io/collector/featuregate v1.59.0/go.mod h1:4ga1QBMPEejXXmpyJS8lmaRpknJ3Lb9Bvk6e420bUFU=
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.153.0 h1:tr5I5hsJPJBbVPGjvOVVPPK4dLR5ZLqVEckuOfnzzMs=
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.153.0/go.mod h1:tFSKiuWKJJgfxANyVnbKPVZkOF7N0bFXvCxCEgqMKuo=
|
||||
go.opentelemetry.io/collector/internal/testutil v0.153.0 h1:GJEaPLohao+7wtm08yGf73RGi1rpIHvqzxOb7Xn8sP0=
|
||||
go.opentelemetry.io/collector/internal/testutil v0.153.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE=
|
||||
go.opentelemetry.io/collector/pdata v1.59.0 h1:lO1IcaO9+HUVdFh+RATCUG3oTP+uCZzsE7HJ0MjmzRc=
|
||||
go.opentelemetry.io/collector/pdata v1.59.0/go.mod h1:AH6M14C6qhesnUpcvigkvFMiX9KtdSWQENMBNyNhe7I=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.153.0 h1:IurcS9g28cVrtIvc1oUVN8vSm5j0t79Pd8GZgd1PV28=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.153.0/go.mod h1:nX33dLKrwdoz/FQeIs6JKPeZcS1KbU2VIOwH7K0F05c=
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.153.0 h1:pO/+b8Rz5PG0G+TskdYdQEjhXnNG2bQoiRRMwic6X0I=
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.153.0/go.mod h1:JVjUfJv9YFL3JUhisxMdLe2DX7we227Ry9JiTgwlEro=
|
||||
go.opentelemetry.io/collector/pipeline v1.59.0 h1:AyEcAPy5ZuUFpqis9i97WEIAcFh/mEEo90+1wr4urNU=
|
||||
go.opentelemetry.io/collector/pipeline v1.59.0/go.mod h1:RD90NG3Jbk965Xaqym3JyHkuol4uZJjQVUkD9ddXJIs=
|
||||
go.opentelemetry.io/collector/processor v1.59.0 h1:uSIMwLaKLzHNiv8625LP3BLUMCqRaBc1ay2o7uW19PQ=
|
||||
go.opentelemetry.io/collector/processor v1.59.0/go.mod h1:IrCFcSdmqIWfNeTWOxncNcdQGVOf0LlKY6A3pHEpGiw=
|
||||
go.opentelemetry.io/collector/processor/processortest v0.153.0 h1:aMH8+omUXs2iCKL4Cphmzzrn4lB4jm6ZgWRvKKV+B/c=
|
||||
go.opentelemetry.io/collector/processor/processortest v0.153.0/go.mod h1:LAPHps5FhQyd0MnNd1ZHmoykG/EWsIpJLs7fivFf5Mc=
|
||||
go.opentelemetry.io/collector/processor/xprocessor v0.153.0 h1:mXtOAwZAXcHgAgVRzAk4NRoyj7yHV88LVFrn0CCedog=
|
||||
go.opentelemetry.io/collector/processor/xprocessor v0.153.0/go.mod h1:yGFU58TvheCedrVkdqU8jW/vnCFqcyYElf+5lidn0nA=
|
||||
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.69.0 h1:MCcYL7J6Vt/X0kjqbMZkekCmwsurbQRbL69vkiye2lk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0/go.mod h1:3jnStNwSufK+f5ktjL4EPcwtig4rtd81NS70lqHuXl8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI=
|
||||
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
|
||||
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
|
||||
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
|
||||
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
|
||||
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
|
||||
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
|
||||
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
|
||||
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
|
||||
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.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
|
||||
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
|
||||
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.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
|
||||
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
|
||||
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.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
||||
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
||||
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.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
||||
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
|
||||
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
|
||||
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.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
|
||||
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
|
||||
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-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
|
||||
google.golang.org/grpc v1.81.1/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=
|
||||
|
|
|
|||
181
go.mod
181
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.18
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.17
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.304.0
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.81.0
|
||||
github.com/aws/aws-sdk-go-v2/service/elasticache v1.52.2
|
||||
github.com/aws/aws-sdk-go-v2/service/kafka v1.52.0
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.54.0
|
||||
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.26.0
|
||||
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.193.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-20260528135333-5b027732945f
|
||||
github.com/hetznercloud/hcloud-go/v2 v2.41.2
|
||||
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.1
|
||||
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.153.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.37.2
|
||||
github.com/pb33f/libopenapi-validator v0.13.8
|
||||
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-20260518105423-c9d5bc4c50a9
|
||||
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.2
|
||||
go.opentelemetry.io/collector/component v1.59.0
|
||||
go.opentelemetry.io/collector/consumer v1.59.0
|
||||
go.opentelemetry.io/collector/pdata v1.59.0
|
||||
go.opentelemetry.io/collector/processor v1.59.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0
|
||||
go.opentelemetry.io/otel v1.44.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0
|
||||
go.opentelemetry.io/otel/metric v1.44.0
|
||||
go.opentelemetry.io/otel/sdk v1.44.0
|
||||
go.opentelemetry.io/otel/trace v1.44.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.45.0
|
||||
golang.org/x/text v0.37.0
|
||||
google.golang.org/api v0.278.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa
|
||||
google.golang.org/grpc v1.81.1
|
||||
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.153.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.36.0 // 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.153.0 // indirect
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.153.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.59.0 // indirect
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.153.0 // indirect
|
||||
go.opentelemetry.io/collector/featuregate v1.59.0 // indirect
|
||||
go.opentelemetry.io/collector/pipeline v1.59.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
|
||||
go.uber.org/zap v1.28.0 // indirect
|
||||
golang.org/x/crypto v0.52.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.36.0 // indirect
|
||||
golang.org/x/net v0.55.0 // indirect
|
||||
golang.org/x/term v0.43.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.45.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // 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
|
||||
|
|
|
|||
420
go.sum
420
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.18 h1:Hcia46bxhGgF3BaSnG8nSNCWmqTK6bj9xN9/FJ3WK6Q=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.18/go.mod h1:zEjCAYmxqDadH1WX8CdBvmLKhUEUVFgKRQG38zjDmrY=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.17 h1:gP2nkGsS+KMvF/jfFz2Vv2qiiOqWKyPACSzPsqHgoW8=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.17/go.mod h1:Bsew3S/moG5iT77giPj1q8wb/s0RE5/QfH+ASjYtuQc=
|
||||
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.304.0 h1:wZthLlYdKxBo7NpWLbl0A/8DB/QNDB+8RJa9WboK9Q0=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.304.0/go.mod h1:Y95W0Hm6FYLPa6o0hbnJ+sWgmdc4ifcLFjGkdobWVhY=
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.81.0 h1:2Sp9EwK7giQpJnQ54k0zdUh6aykmmbpEurEEygr104c=
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.81.0/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.52.0 h1:jalIJqKvZMvJRvs6ABLX+FhHz8E9pjU03Pyml4D9r3k=
|
||||
github.com/aws/aws-sdk-go-v2/service/kafka v1.52.0/go.mod h1:pW4pYNuVeScl13yqwsjLY0F/7g2YD8E0AvR6SOQsJZE=
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.54.0 h1:07DKnL5eKSel3XEM2UxlD/z9zUZZ6XMHLGDXkAdY4u8=
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.54.0/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.36.0 h1:nDARhv/oF55bcxF7rCI/4PDxOKnVXVWwDuDwCs2I2SQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.36.0/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.26.0 h1:9ouqbi+NyKP7fV3Te7UElCwdAb6Y8uk7LGwPE5tVe/s=
|
||||
github.com/aws/smithy-go v1.26.0/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.193.0 h1:CSbbUl5LufT75KPNvex3vDnBYjY2RfJWs7T3Ac7dHpA=
|
||||
github.com/digitalocean/godo v1.193.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-20260528135333-5b027732945f h1:sdf4a6FF3tC1/c0buuizLAwZa/xLu4gWD87qWrzQLvo=
|
||||
github.com/hashicorp/nomad/api v0.0.0-20260528135333-5b027732945f/go.mod h1:Kr8imJwigbQ/50BqVae2+JL+AyX+FnzbnuCoIFb6iYg=
|
||||
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.41.2 h1:fO5zsMgp5oejrtnFj8mYuqlp+iMuirpaKv4b5FYNRdQ=
|
||||
github.com/hetznercloud/hcloud-go/v2 v2.41.2/go.mod h1:9OGvC//jbHE4sv2Oyo0bQ2vEWuUMKYoNMyj9Qxz2qcc=
|
||||
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.1 h1:f45N2MHR/oece2/ktTTCYmrlfse4//k3NgwcF5zbGZ0=
|
||||
github.com/linode/linodego v1.69.1/go.mod h1:Fha0NYsQSx5VZK1HQNJY/z/dIxxkFp+vb5veawbmAUw=
|
||||
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.153.0 h1:hrLQLVZ4YXs35G9QvPO+xcu6qMnUpCt3WOpBDM7dR+E=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.153.0/go.mod h1:+qlIXDaBLIX+egj/okymUG88KSdAD8nIEHY8+tXt8+M=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.153.0 h1:kPPv0sQQH2R2CitTPYXDfq1z1ekStnmk39C8RkOrsbI=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.153.0/go.mod h1:wFACQmv2KfJyvyiRtMrI/DmcOWKEk6SxY0nLduWFMC4=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.153.0 h1:3MR2JvG1KB4GUiMi5asE6K0Ln5cjWPEfVAIpUwf55Sk=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor v0.153.0/go.mod h1:0lEaZGCEjzb4R5J6F0NR1jF1KKc18IkvPRwLpQuyyjY=
|
||||
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.37.2 h1:4Kb4w/h2BVKb099oYIZqeDxEBhUioWA+z6WJhBOk2r8=
|
||||
github.com/pb33f/libopenapi v0.37.2/go.mod h1:MsDdUlQ1CdrIDO5v26JfgBxQs7kcaOUEpMP3EqU6bI4=
|
||||
github.com/pb33f/libopenapi-validator v0.13.8 h1:3t/5hUq8EYIWe6Uwj5RA7xFSWkleDbqsueA78/tIAo8=
|
||||
github.com/pb33f/libopenapi-validator v0.13.8/go.mod h1:mWwedExRS1L8gjK6BGE1oDA5wXLuxgU7EheNz703MCg=
|
||||
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-20260518105423-c9d5bc4c50a9 h1:e33IfrrwrJkylWwAGcQ2jMvbWVv13lv0suTXjGNeiqY=
|
||||
github.com/prometheus/client_golang/exp v0.0.0-20260518105423-c9d5bc4c50a9/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=
|
||||
|
|
@ -533,16 +533,16 @@ github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36 h1:ObX9hZmK+VmijreZO/8x9pQ8/P
|
|||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.36/go.mod h1:LEsDu4BubxK7/cWhtlQWfuxwL4rf/2UEpxXz1o1EMtM=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shoenig/test v1.12.2 h1:ZVT8NeIUwGWpZcKaepPmFMoNQ3sVpxvqUh/MAqwFiJI=
|
||||
github.com/shoenig/test v1.12.2/go.mod h1:UxJ6u/x2v/TNs/LoLxBNJRV9DiwBBKYxXSyczsBHFoI=
|
||||
github.com/shoenig/test v1.13.2 h1:SaGxHxg7xkRuKuNtuFmHf0LgNGaAgcBT7HN4WHCKfqU=
|
||||
github.com/shoenig/test v1.13.2/go.mod h1:MKmiRyEeuFl8y9PCoThaRDgYQZeWBhRQlH99poXz5LI=
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
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.2 h1:2l3/KDvfemG+4azw4LLquJoh9mFOAVEdBXtPPzix3ac=
|
||||
github.com/vultr/govultr/v3 v3.31.2/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.59.0 h1:WtulkwzsdAOM/LE0cH/IiudUgiyb2ueVDDeEh5HsXzo=
|
||||
go.opentelemetry.io/collector/component v1.59.0/go.mod h1:5eQCM0tS6qbG2XJ6Bt67kgCxuhCbg4csVv6SywyHZ6w=
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.153.0 h1:bZu1Qs1eHw5ZY2UEKq0f5IcctDgc6zjUYwCE1T22Tmw=
|
||||
go.opentelemetry.io/collector/component/componentstatus v0.153.0/go.mod h1:SfYWwh6pA9jJUcjuX+zIJ9kyn+2Z9SSLMM3xYOBsVW4=
|
||||
go.opentelemetry.io/collector/component/componenttest v0.153.0 h1:u6O1l+9PUNnI22k8q4sF9wgLAUyt+y2Ov7xi1yZ+wE4=
|
||||
go.opentelemetry.io/collector/component/componenttest v0.153.0/go.mod h1:Ym/d5UxnoHmrCI5LsVANBicikNiqtwjk8uWBM+Z4jDM=
|
||||
go.opentelemetry.io/collector/confmap v1.59.0 h1:asxEEiWwNuGfmTVSctYArOTF8jcxYpS4NmPtvvFhNNI=
|
||||
go.opentelemetry.io/collector/confmap v1.59.0/go.mod h1:X5SjFINrF0cb0hcM8PwnW2z+0L/pHA1H1yPPtm2j0tY=
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.153.0 h1:RSn7C87eBp1iuWip3hX8v9AR8adMze1usJxwumefkq4=
|
||||
go.opentelemetry.io/collector/confmap/xconfmap v0.153.0/go.mod h1:4SuPyutUiirRqQoPeY+13lLYkOQ2opMQgKvKACnXh1k=
|
||||
go.opentelemetry.io/collector/consumer v1.59.0 h1:EFDQ8ZTWwHEratWusKgW26W20LeAWdXj235iD9MxpuA=
|
||||
go.opentelemetry.io/collector/consumer v1.59.0/go.mod h1:wrOSfXkKjzEeHYxhKGukuB9+NFV/CboWwEH1oEXhMtw=
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.153.0 h1:fCqkOWNVK/qipg4SX60zICs3jhKDjcrtF1oxJR6msCk=
|
||||
go.opentelemetry.io/collector/consumer/consumertest v0.153.0/go.mod h1:YfVqyCrvEfvsbbrpfiH97fITh4vmIBzZT112tUluqx0=
|
||||
go.opentelemetry.io/collector/consumer/xconsumer v0.153.0 h1:Jt1Aiiq9zDILzppRTEdZXaA830KBjjP1i2kWL+h5br0=
|
||||
go.opentelemetry.io/collector/consumer/xconsumer v0.153.0/go.mod h1:IzJ/dTOtEUMjY0DYu6kO946u5jbiDDUG8+sLaLhJ+HY=
|
||||
go.opentelemetry.io/collector/featuregate v1.59.0 h1:pu70/9eWRjAjzGnr3VmqwY+k6fmU3esLp15AqxfBBz0=
|
||||
go.opentelemetry.io/collector/featuregate v1.59.0/go.mod h1:4ga1QBMPEejXXmpyJS8lmaRpknJ3Lb9Bvk6e420bUFU=
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.153.0 h1:tr5I5hsJPJBbVPGjvOVVPPK4dLR5ZLqVEckuOfnzzMs=
|
||||
go.opentelemetry.io/collector/internal/componentalias v0.153.0/go.mod h1:tFSKiuWKJJgfxANyVnbKPVZkOF7N0bFXvCxCEgqMKuo=
|
||||
go.opentelemetry.io/collector/internal/testutil v0.153.0 h1:GJEaPLohao+7wtm08yGf73RGi1rpIHvqzxOb7Xn8sP0=
|
||||
go.opentelemetry.io/collector/internal/testutil v0.153.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE=
|
||||
go.opentelemetry.io/collector/pdata v1.59.0 h1:lO1IcaO9+HUVdFh+RATCUG3oTP+uCZzsE7HJ0MjmzRc=
|
||||
go.opentelemetry.io/collector/pdata v1.59.0/go.mod h1:AH6M14C6qhesnUpcvigkvFMiX9KtdSWQENMBNyNhe7I=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.153.0 h1:IurcS9g28cVrtIvc1oUVN8vSm5j0t79Pd8GZgd1PV28=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.153.0/go.mod h1:nX33dLKrwdoz/FQeIs6JKPeZcS1KbU2VIOwH7K0F05c=
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.153.0 h1:pO/+b8Rz5PG0G+TskdYdQEjhXnNG2bQoiRRMwic6X0I=
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.153.0/go.mod h1:JVjUfJv9YFL3JUhisxMdLe2DX7we227Ry9JiTgwlEro=
|
||||
go.opentelemetry.io/collector/pipeline v1.59.0 h1:AyEcAPy5ZuUFpqis9i97WEIAcFh/mEEo90+1wr4urNU=
|
||||
go.opentelemetry.io/collector/pipeline v1.59.0/go.mod h1:RD90NG3Jbk965Xaqym3JyHkuol4uZJjQVUkD9ddXJIs=
|
||||
go.opentelemetry.io/collector/processor v1.59.0 h1:uSIMwLaKLzHNiv8625LP3BLUMCqRaBc1ay2o7uW19PQ=
|
||||
go.opentelemetry.io/collector/processor v1.59.0/go.mod h1:IrCFcSdmqIWfNeTWOxncNcdQGVOf0LlKY6A3pHEpGiw=
|
||||
go.opentelemetry.io/collector/processor/processortest v0.153.0 h1:aMH8+omUXs2iCKL4Cphmzzrn4lB4jm6ZgWRvKKV+B/c=
|
||||
go.opentelemetry.io/collector/processor/processortest v0.153.0/go.mod h1:LAPHps5FhQyd0MnNd1ZHmoykG/EWsIpJLs7fivFf5Mc=
|
||||
go.opentelemetry.io/collector/processor/xprocessor v0.153.0 h1:mXtOAwZAXcHgAgVRzAk4NRoyj7yHV88LVFrn0CCedog=
|
||||
go.opentelemetry.io/collector/processor/xprocessor v0.153.0/go.mod h1:yGFU58TvheCedrVkdqU8jW/vnCFqcyYElf+5lidn0nA=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0 h1:MCcYL7J6Vt/X0kjqbMZkekCmwsurbQRbL69vkiye2lk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0/go.mod h1:3jnStNwSufK+f5ktjL4EPcwtig4rtd81NS70lqHuXl8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI=
|
||||
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
|
||||
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 h1:qazEJlUOQzhCpzQpFETGby7EdqjI1wsd0W+6Gg1SCTU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0/go.mod h1:fOD2Yefuxixkx3ahVNf0O/PERb6r4OlbxfATVnYvzCo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 h1:lgh3PiVrRUWMLOVSkQicxzZll5NjF1r+AtsX1XRIHw0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0/go.mod h1:5Cnhth3m/AgOeTgE3ex12pPmiu/gGtZit03kSzx9X7s=
|
||||
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
|
||||
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
|
||||
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
|
||||
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
|
||||
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
|
||||
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
|
||||
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.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
|
||||
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
|
||||
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.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
|
||||
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
|
||||
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.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
||||
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
||||
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.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
||||
golang.org/x/sys v0.45.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.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
|
||||
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
|
||||
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.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
|
||||
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
|
||||
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-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
|
||||
google.golang.org/grpc v1.81.1/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=
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -70,7 +71,7 @@ require (
|
|||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/quic-go/qpack v0.6.0 // indirect
|
||||
github.com/quic-go/quic-go v0.59.0 // indirect
|
||||
github.com/quic-go/quic-go v0.59.1 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rs/cors v1.11.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
|
|
@ -87,30 +88,31 @@ 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.69.0 // indirect
|
||||
go.opentelemetry.io/otel v1.44.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.44.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.44.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.52.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.36.0 // indirect
|
||||
golang.org/x/net v0.55.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.45.0 // indirect
|
||||
golang.org/x/term v0.43.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
|
||||
golang.org/x/tools v0.45.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
|
||||
google.golang.org/grpc v1.81.1 // 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
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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=
|
||||
|
|
@ -157,8 +157,8 @@ github.com/protocolbuffers/protoscope v0.0.0-20221109213918-8e7a6aafa2c9 h1:arwj
|
|||
github.com/protocolbuffers/protoscope v0.0.0-20221109213918-8e7a6aafa2c9/go.mod h1:SKZx6stCn03JN3BOWTwvVIO2ajMkb/zQdTceXYhKw/4=
|
||||
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
|
||||
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||
github.com/quic-go/quic-go v0.59.1 h1:0Gmua0HW1Tv7ANR7hUYwRyD0MG5OJfgvYSZasGZzBic=
|
||||
github.com/quic-go/quic-go v0.59.1/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rodaine/protogofakeit v0.1.1 h1:ZKouljuRM3A+TArppfBqnH8tGZHOwM/pjvtXe9DaXH8=
|
||||
|
|
@ -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.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI=
|
||||
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
|
||||
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 h1:lgh3PiVrRUWMLOVSkQicxzZll5NjF1r+AtsX1XRIHw0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0/go.mod h1:5Cnhth3m/AgOeTgE3ex12pPmiu/gGtZit03kSzx9X7s=
|
||||
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
|
||||
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
|
||||
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
|
||||
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
|
||||
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
|
||||
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
|
||||
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.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
|
||||
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
|
||||
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.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
|
||||
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
|
||||
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.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
||||
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
||||
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.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
||||
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
|
||||
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
|
||||
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.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8=
|
||||
golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0=
|
||||
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-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
|
||||
google.golang.org/grpc v1.81.1/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=
|
||||
|
|
|
|||
|
|
@ -27,6 +27,13 @@ func mustNewMatcher(t *testing.T, mType MatchType, value string) *Matcher {
|
|||
return m
|
||||
}
|
||||
|
||||
func (m *Matcher) hasCaseInsensitivePrefix() bool {
|
||||
if m.re == nil {
|
||||
return false
|
||||
}
|
||||
return m.re.caseInsensitivePrefix
|
||||
}
|
||||
|
||||
func TestMatcher(t *testing.T) {
|
||||
tests := []struct {
|
||||
matcher *Matcher
|
||||
|
|
@ -137,8 +144,9 @@ func TestInverse(t *testing.T) {
|
|||
|
||||
func TestPrefix(t *testing.T) {
|
||||
for i, tc := range []struct {
|
||||
matcher *Matcher
|
||||
prefix string
|
||||
matcher *Matcher
|
||||
prefix string
|
||||
caseInsensitivePrefix bool
|
||||
}{
|
||||
{
|
||||
matcher: mustNewMatcher(t, MatchEqual, "abc"),
|
||||
|
|
@ -180,9 +188,15 @@ func TestPrefix(t *testing.T) {
|
|||
matcher: mustNewMatcher(t, MatchRegexp, ".+def"),
|
||||
prefix: "",
|
||||
},
|
||||
{
|
||||
matcher: mustNewMatcher(t, MatchNotRegexp, "(?i)abc.+"),
|
||||
prefix: "ABC",
|
||||
caseInsensitivePrefix: true,
|
||||
},
|
||||
} {
|
||||
t.Run(fmt.Sprintf("%d: %s", i, tc.matcher), func(t *testing.T) {
|
||||
require.Equal(t, tc.prefix, tc.matcher.Prefix())
|
||||
require.Equal(t, tc.caseInsensitivePrefix, tc.matcher.hasCaseInsensitivePrefix())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ type FastRegexMatcher struct {
|
|||
suffix string
|
||||
contains []string
|
||||
|
||||
// caseInsensitivePrefix is true if prefix exists and should be matched case-insensitively
|
||||
caseInsensitivePrefix bool
|
||||
|
||||
// matchString is the "compiled" function to run by MatchString().
|
||||
matchString func(string) bool
|
||||
}
|
||||
|
|
@ -79,7 +82,7 @@ func NewFastRegexMatcher(v string) (*FastRegexMatcher, error) {
|
|||
clearCapture(parsed)
|
||||
|
||||
if parsed.Op == syntax.OpConcat {
|
||||
m.prefix, m.suffix, m.contains = optimizeConcatRegex(parsed)
|
||||
m.caseInsensitivePrefix, m.prefix, m.suffix, m.contains = optimizeConcatRegex(parsed)
|
||||
}
|
||||
if matches, caseSensitive := findSetMatches(parsed); caseSensitive {
|
||||
m.setMatches = matches
|
||||
|
|
@ -109,6 +112,15 @@ func (m *FastRegexMatcher) compileMatchStringFunction() func(string) bool {
|
|||
return m.stringMatcher.Matches
|
||||
}
|
||||
|
||||
if m.caseInsensitivePrefix && m.prefix != "" {
|
||||
return func(s string) bool {
|
||||
if !hasPrefixCaseInsensitive(s, m.prefix) {
|
||||
return false
|
||||
}
|
||||
return m.re.MatchString(s)
|
||||
}
|
||||
}
|
||||
|
||||
return func(s string) bool {
|
||||
if len(m.setMatches) != 0 {
|
||||
return slices.Contains(m.setMatches, s)
|
||||
|
|
@ -411,7 +423,7 @@ func optimizeAlternatingSimpleContains(r *syntax.Regexp) *syntax.Regexp {
|
|||
|
||||
// optimizeConcatRegex returns literal prefix/suffix text that can be safely
|
||||
// checked against the label value before running the regexp matcher.
|
||||
func optimizeConcatRegex(r *syntax.Regexp) (prefix, suffix string, contains []string) {
|
||||
func optimizeConcatRegex(r *syntax.Regexp) (caseInsensitivePrefix bool, prefix, suffix string, contains []string) {
|
||||
sub := r.Sub
|
||||
clearCapture(sub...)
|
||||
|
||||
|
|
@ -425,14 +437,15 @@ func optimizeConcatRegex(r *syntax.Regexp) (prefix, suffix string, contains []st
|
|||
}
|
||||
|
||||
if len(sub) == 0 {
|
||||
return prefix, suffix, contains
|
||||
return caseInsensitivePrefix, prefix, suffix, contains
|
||||
}
|
||||
|
||||
// Given Prometheus regex matchers are always anchored to the begin/end
|
||||
// of the text, if the first/last operations are literals, we can safely
|
||||
// treat them as prefix/suffix.
|
||||
if sub[0].Op == syntax.OpLiteral && (sub[0].Flags&syntax.FoldCase) == 0 {
|
||||
if sub[0].Op == syntax.OpLiteral {
|
||||
prefix = string(sub[0].Rune)
|
||||
caseInsensitivePrefix = (sub[0].Flags & syntax.FoldCase) != 0
|
||||
}
|
||||
if last := len(sub) - 1; sub[last].Op == syntax.OpLiteral && (sub[last].Flags&syntax.FoldCase) == 0 {
|
||||
suffix = string(sub[last].Rune)
|
||||
|
|
@ -446,7 +459,7 @@ func optimizeConcatRegex(r *syntax.Regexp) (prefix, suffix string, contains []st
|
|||
}
|
||||
}
|
||||
|
||||
return prefix, suffix, contains
|
||||
return caseInsensitivePrefix, prefix, suffix, contains
|
||||
}
|
||||
|
||||
// StringMatcher is a matcher that matches a string in place of a regular expression.
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ var (
|
|||
".*foo.*",
|
||||
".+foo.+",
|
||||
".*foo.*|",
|
||||
"(?i).*foo.*",
|
||||
".*foo.*|bar.*",
|
||||
"foo.*|.*bar.*",
|
||||
".*foo.*|.*bar.*",
|
||||
|
|
@ -67,6 +68,8 @@ var (
|
|||
"10\\.0\\.(1|2)\\.+",
|
||||
"10\\.0\\.(1|2).+",
|
||||
"((fo(bar))|.+foo)",
|
||||
"(?i)report.scheduled.job_runscheduledreports",
|
||||
"report.scheduled.job_runscheduledreports",
|
||||
// A long case sensitive alternation.
|
||||
"zQPbMkNO|NNSPdvMi|iWuuSoAl|qbvKMimS|IecrXtPa|seTckYqt|NxnyHkgB|fIDlOgKb|UhlWIygH|OtNoJxHG|cUTkFVIV|mTgFIHjr|jQkoIDtE|PPMKxRXl|AwMfwVkQ|CQyMrTQJ|BzrqxVSi|nTpcWuhF|PertdywG|ZZDgCtXN|WWdDPyyE|uVtNQsKk|BdeCHvPZ|wshRnFlH|aOUIitIp|RxZeCdXT|CFZMslCj|AVBZRDxl|IzIGCnhw|ythYuWiz|oztXVXhl|VbLkwqQx|qvaUgyVC|VawUjPWC|ecloYJuj|boCLTdSU|uPrKeAZx|hrMWLWBq|JOnUNHRM|rYnujkPq|dDEdZhIj|DRrfvugG|yEGfDxVV|YMYdJWuP|PHUQZNWM|AmKNrLis|zTxndVfn|FPsHoJnc|EIulZTua|KlAPhdzg|ScHJJCLt|NtTfMzME|eMCwuFdo|SEpJVJbR|cdhXZeCx|sAVtBwRh|kVFEVcMI|jzJrxraA|tGLHTell|NNWoeSaw|DcOKSetX|UXZAJyka|THpMphDP|rizheevl|kDCBRidd|pCZZRqyu|pSygkitl|SwZGkAaW|wILOrfNX|QkwVOerj|kHOMxPDr|EwOVycJv|AJvtzQFS|yEOjKYYB|LizIINLL|JBRSsfcG|YPiUqqNl|IsdEbvee|MjEpGcBm|OxXZVgEQ|xClXGuxa|UzRCGFEb|buJbvfvA|IPZQxRet|oFYShsMc|oBHffuHO|bzzKrcBR|KAjzrGCl|IPUsAVls|OGMUMbIU|gyDccHuR|bjlalnDd|ZLWjeMna|fdsuIlxQ|dVXtiomV|XxedTjNg|XWMHlNoA|nnyqArQX|opfkWGhb|wYtnhdYb",
|
||||
// An extremely long case sensitive alternation. This is a special
|
||||
|
|
@ -108,6 +111,7 @@ var (
|
|||
"foo", " foo bar", "bar", "buzz\nbar", "bar foo", "bfoo", "\n", "\nfoo", "foo\n", "hello foo world", "hello foo\n world", "",
|
||||
"FOO", "Foo", "fOo", "foO", "OO", "Oo", "\nfoo\n", strings.Repeat("f", 20), "prometheus", "prometheus_api_v1", "prometheus_api_v1_foo",
|
||||
"10.0.1.20", "10.0.2.10", "10.0.3.30", "10.0.4.40",
|
||||
"report.scheduled.job_runscheduledreports", "Report.Scheduled.JobRunScheduledReports", "Report.Scheduled.Job_RunScheduledReports",
|
||||
"foofoo0", "foofoo", "😀foo0", "ſſs", "ſſS", "AAAAAAAAAAAAAAAAAAAAAAAA", "BBBBBBBBBBBBBBBBBBBBBBBB", "cccccccccccccccccccccccC", "ſſſſſſſſſſſſſſſſſſſſſſſſS", "SSSSSSSSSSSSSSSSSSSSSSSSſ",
|
||||
"a-b-c-d-e",
|
||||
"aaaaaa-bbbbbb-cccccc-dddddd-eeeeee",
|
||||
|
|
@ -154,10 +158,11 @@ func readable(s string) string {
|
|||
|
||||
func TestOptimizeConcatRegex(t *testing.T) {
|
||||
cases := []struct {
|
||||
regex string
|
||||
prefix string
|
||||
suffix string
|
||||
contains []string
|
||||
regex string
|
||||
prefix string
|
||||
isCaseInsensitivePrefix bool
|
||||
suffix string
|
||||
contains []string
|
||||
}{
|
||||
{regex: "foo(hello|bar)", prefix: "foo", suffix: "", contains: nil},
|
||||
{regex: "foo(hello|bar)world", prefix: "foo", suffix: "world", contains: nil},
|
||||
|
|
@ -171,12 +176,12 @@ func TestOptimizeConcatRegex(t *testing.T) {
|
|||
{regex: ".*[abc].*", prefix: "", suffix: "", contains: nil},
|
||||
{regex: ".*((?i)abc).*", prefix: "", suffix: "", contains: nil},
|
||||
{regex: ".*(?i:abc).*", prefix: "", suffix: "", contains: nil},
|
||||
{regex: "(?i:abc).*", prefix: "", suffix: "", contains: nil},
|
||||
{regex: "(?i:abc).*", prefix: "ABC", isCaseInsensitivePrefix: true, suffix: "", contains: nil},
|
||||
{regex: ".*(?i:abc)", prefix: "", suffix: "", contains: nil},
|
||||
{regex: ".*(?i:abc)def.*", prefix: "", suffix: "", contains: []string{"def"}},
|
||||
{regex: "(?i).*(?-i:abc)def", prefix: "", suffix: "", contains: []string{"abc"}},
|
||||
{regex: ".*(?msU:abc).*", prefix: "", suffix: "", contains: []string{"abc"}},
|
||||
{regex: "[aA]bc.*", prefix: "", suffix: "", contains: []string{"bc"}},
|
||||
{regex: "[aA]bc.*", prefix: "A", isCaseInsensitivePrefix: true, suffix: "", contains: []string{"bc"}},
|
||||
{regex: "^5..$", prefix: "5", suffix: "", contains: nil},
|
||||
{regex: "^release.*", prefix: "release", suffix: "", contains: nil},
|
||||
{regex: "^env-[0-9]+laio[1]?[^0-9].*", prefix: "env-", suffix: "", contains: []string{"laio"}},
|
||||
|
|
@ -184,13 +189,16 @@ func TestOptimizeConcatRegex(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, c := range cases {
|
||||
parsed, err := syntax.Parse(c.regex, syntax.Perl|syntax.DotNL)
|
||||
require.NoError(t, err)
|
||||
t.Run(c.regex, func(t *testing.T) {
|
||||
parsed, err := syntax.Parse(c.regex, syntax.Perl|syntax.DotNL)
|
||||
require.NoError(t, err)
|
||||
|
||||
prefix, suffix, contains := optimizeConcatRegex(parsed)
|
||||
require.Equal(t, c.prefix, prefix)
|
||||
require.Equal(t, c.suffix, suffix)
|
||||
require.Equal(t, c.contains, contains)
|
||||
caseInsensitivePrefix, prefix, suffix, contains := optimizeConcatRegex(parsed)
|
||||
require.Equal(t, c.prefix, prefix)
|
||||
require.Equal(t, c.isCaseInsensitivePrefix, caseInsensitivePrefix)
|
||||
require.Equal(t, c.suffix, suffix)
|
||||
require.Equal(t, c.contains, contains)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -432,6 +440,8 @@ func TestNewFastRegexMatcher(t *testing.T) {
|
|||
{"foo.?", &literalPrefixSensitiveStringMatcher{prefix: "foo", right: &zeroOrOneCharacterStringMatcher{matchNL: true}}},
|
||||
{"f.?o", nil},
|
||||
{".*foo.*|.*bar.*|.*baz.*", &containsStringMatcher{left: trueMatcher{}, substrings: []string{"foo", "bar", "baz"}, right: trueMatcher{}}},
|
||||
{"(?i)report.scheduled.job_runscheduledreports", nil},
|
||||
{"report.scheduled.job_runscheduledreports", nil},
|
||||
} {
|
||||
t.Run(c.pattern, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
|
|
|||
|
|
@ -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{}),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
package writev2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/prometheus/common/model"
|
||||
|
||||
"github.com/prometheus/prometheus/model/exemplar"
|
||||
|
|
@ -29,8 +31,8 @@ func (m TimeSeries) ToLabels(b *labels.ScratchBuilder, symbols []string) (labels
|
|||
return desymbolizeLabels(b, m.GetLabelsRefs(), symbols)
|
||||
}
|
||||
|
||||
// ToMetadata return model metadata from timeseries' remote metadata.
|
||||
func (m TimeSeries) ToMetadata(symbols []string) metadata.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 {
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -124,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.MIN_OF:
|
||||
return math.Min(lhs, rhs), nil
|
||||
case parser.MAX:
|
||||
case parser.MAX_OF:
|
||||
return math.Max(lhs, rhs), nil
|
||||
case parser.ADD:
|
||||
if n.LHS == nil {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
) +
|
||||
|
|
@ -228,7 +228,7 @@ func TestCalculateDuration(t *testing.T) {
|
|||
expected: 150 * time.Second,
|
||||
},
|
||||
{
|
||||
name: "max of step and range",
|
||||
name: "max_of 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.MAX_OF,
|
||||
},
|
||||
expected: 5 * time.Minute,
|
||||
},
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
108
promql/engine.go
108
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()}
|
||||
|
|
@ -1737,6 +1738,7 @@ func (ev *evaluator) smoothSeries(series []storage.Series, offset time.Duration)
|
|||
|
||||
var floats []FPoint
|
||||
var hists []HPoint
|
||||
metricName := s.Labels().Get(labels.MetricName)
|
||||
|
||||
for evalTS := ev.startTimestamp; evalTS <= ev.endTimestamp; evalTS += step {
|
||||
// Apply offset to get the data timestamp.
|
||||
|
|
@ -1749,40 +1751,80 @@ 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(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(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 {
|
||||
annosFromInterpolationError(&annos, err, 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.
|
||||
// CounterResetHint is reset to UnknownCounterReset because the hint
|
||||
// describes the relationship between consecutive samples, not the value.
|
||||
prev := hists[i-1]
|
||||
h := prev.H.Copy()
|
||||
h.CounterResetHint = histogram.UnknownCounterReset
|
||||
ss.Histograms = append(ss.Histograms, HPoint{H: h, 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.
|
||||
|
|
@ -2021,6 +2063,11 @@ func (ev *evaluator) eval(ctx context.Context, expr parser.Expr) (parser.Value,
|
|||
return ev.evalInfo(ctx, e.Args)
|
||||
}
|
||||
|
||||
// Functions with nil entries in FunctionCalls should have been handled before reaching this point.
|
||||
if call == nil {
|
||||
panic(fmt.Errorf("unexpected nil implementation for function %q", e.Func.Name))
|
||||
}
|
||||
|
||||
// Emit a warning when sort is used for range queries.
|
||||
if (e.Func.Name == "sort" || e.Func.Name == "sort_desc" || e.Func.Name == "sort_by_label" || e.Func.Name == "sort_by_label_desc") && ev.startTimestamp != ev.endTimestamp {
|
||||
warnings.Add(annotations.NewSortInRangeQueryWarning(e.PositionRange()))
|
||||
|
|
@ -2100,7 +2147,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{}
|
||||
}
|
||||
|
|
@ -2178,12 +2225,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 +2419,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)
|
||||
|
|
@ -2722,7 +2764,7 @@ func (ev *evaluator) matrixSelector(ctx context.Context, node *parser.MatrixSele
|
|||
ss.Floats = extendFloats(ss.Floats, matrixMint, matrixMaxt, false)
|
||||
case vs.Smoothed:
|
||||
if ss.Histograms != nil {
|
||||
ev.errorf("anchored modifier is not supported with histograms")
|
||||
ev.errorf("smoothed modifier is not supported with histograms")
|
||||
}
|
||||
ss.Floats = extendFloats(ss.Floats, matrixMint, matrixMaxt, true)
|
||||
}
|
||||
|
|
@ -3179,7 +3221,7 @@ func (ev *evaluator) VectorBinop(op parser.ItemType, lhs, rhs Vector, matching *
|
|||
sigOrd := rhsh[i].sigOrdinal
|
||||
|
||||
if (matching.Card == parser.CardOneToOne && matchedSigsPresent[sigOrd]) ||
|
||||
(matching.Card != parser.CardOneToOne && matchedSigs[sigOrd] != nil) {
|
||||
(matching.Card != parser.CardOneToOne && len(matchedSigs[sigOrd]) > 0) {
|
||||
continue // Already matched.
|
||||
}
|
||||
ls := Sample{
|
||||
|
|
|
|||
|
|
@ -59,13 +59,6 @@ import (
|
|||
// Scalar results should be returned as the value of a sample in a Vector.
|
||||
type FunctionCall func(vectorVals []Vector, matrixVals Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations)
|
||||
|
||||
// funcQueryContext is a placeholder for start(), end(), range(), and step() functions.
|
||||
// These are folded into NumberLiteral nodes by foldQueryContextFunctions during query
|
||||
// preprocessing and must never reach the evaluator.
|
||||
func funcQueryContext(_ []Vector, _ Matrix, _ parser.Expressions, _ *EvalNodeHelper) (Vector, annotations.Annotations) {
|
||||
panic("query context functions must be folded during preprocessing and must never be evaluated")
|
||||
}
|
||||
|
||||
// === time() float64 ===
|
||||
func funcTime(_ []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
|
||||
return Vector{Sample{
|
||||
|
|
@ -107,6 +100,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.
|
||||
result := h2.Copy()
|
||||
_, _, nhcbReconciled, err := result.Sub(h1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if nhcbReconciled {
|
||||
annos.Add(annotations.NewMismatchedCustomBucketsHistogramsInfo(pos, annotations.HistogramSub))
|
||||
}
|
||||
result.Mul(fraction)
|
||||
_, _, nhcbReconciled, err = result.Add(h1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if nhcbReconciled {
|
||||
annos.Add(annotations.NewMismatchedCustomBucketsHistogramsInfo(pos, annotations.HistogramAdd))
|
||||
}
|
||||
return result, 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,9 +177,134 @@ 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 left unchanged.
|
||||
func annosFromInterpolationError(annos *annotations.Annotations, err error, metricName string, pos posrange.PositionRange) {
|
||||
if errors.Is(err, histogram.ErrHistogramsIncompatibleSchema) {
|
||||
annos.Add(annotations.NewMixedExponentialCustomHistogramsWarning(metricName, pos))
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// correctForCounterResetsHistogram calculates the histogram correction for
|
||||
// counter resets between firstSampleIndex and lastSampleIndex in h, using
|
||||
// left and right as the boundary values. It mirrors correctForCounterResets
|
||||
// for float samples. It returns the accumulated correction (nil if none),
|
||||
// any annotations, and false if combining histograms failed.
|
||||
func correctForCounterResetsHistogram(h []HPoint, firstSampleIndex, lastSampleIndex int, left, right *histogram.FloatHistogram, rangeStart int64, smoothed bool, metricName string, pos posrange.PositionRange) (*histogram.FloatHistogram, annotations.Annotations, bool) {
|
||||
// firstSampleIndex is represented by left, so the loop starts one beyond.
|
||||
first := firstSampleIndex + 1
|
||||
prev := left
|
||||
if smoothed && h[firstSampleIndex].T < rangeStart && h[firstSampleIndex+1].H.DetectReset(h[firstSampleIndex].H) {
|
||||
// The left interpolation spanned the reset between h[firstSampleIndex]
|
||||
// and h[firstSampleIndex+1]. That reset is already accounted for, so
|
||||
// skip h[firstSampleIndex+1] from the loop and use it as the comparison
|
||||
// anchor for any reset that immediately follows.
|
||||
prev = h[firstSampleIndex+1].H
|
||||
first++
|
||||
}
|
||||
// lastSampleIndex is always excluded: right is either a direct copy of
|
||||
// h[lastSampleIndex] or an interpolation that inherits its CounterResetHint.
|
||||
// Including h[lastSampleIndex] in the loop would make right.DetectReset
|
||||
// self-detect on the same hint. The final right.DetectReset(prev) below
|
||||
// handles the right-boundary reset safely once h[lastSampleIndex] is not prev.
|
||||
last := lastSampleIndex - 1
|
||||
|
||||
// first > last+1 when there is nothing between the two boundary samples to
|
||||
// check. This happens when firstSampleIndex == lastSampleIndex (single-sample
|
||||
// window), or when the smoothed left interpolation already spanned the only
|
||||
// reset interval (lastSampleIndex == firstSampleIndex+1 and first was
|
||||
// incremented above). Both boundaries were interpolated from the same reset
|
||||
// segment, so there is nothing more to correct.
|
||||
if first > last+1 {
|
||||
return nil, nil, true
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
for _, p := range h[first : last+1] {
|
||||
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
|
||||
// interpolates at the first/last sample boundary if needed, and returns
|
||||
// the result as either per-second (if isRate is true) or overall.
|
||||
func extendedRate(vals Matrix, args parser.Expressions, enh *EvalNodeHelper, isCounter, isRate bool) (Vector, annotations.Annotations) {
|
||||
var (
|
||||
|
|
@ -178,18 +356,116 @@ 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.
|
||||
//
|
||||
// TODO: histogramRate pre-computes the minimum exponential schema across all
|
||||
// samples and reduces every sample to that schema before doing arithmetic, so
|
||||
// the schema is reduced at most once. extendedHistogramRate reduces schema on
|
||||
// the fly during pairwise Sub/Add operations. In the common constant-schema
|
||||
// case both produce identical results. In mixed-schema cases the final schema
|
||||
// is also the same (global minimum wins either way), but intermediate values
|
||||
// may briefly sit at a higher resolution before being pulled down when the
|
||||
// correction is added. Aligning the two approaches requires a min-schema
|
||||
// pre-scan followed by CopyToSchema on the interpolated boundaries, which is
|
||||
// a non-trivial change and warrants its own PR.
|
||||
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
|
||||
}
|
||||
|
||||
if !validateHistogramRange(h[firstSampleIndex:lastSampleIndex+1], isCounter, &annos, metricName, pos) {
|
||||
return enh.Out, annos
|
||||
}
|
||||
|
||||
left, err := pickOrInterpolateLeftHistogram(h, firstSampleIndex, rangeStart, smoothed, isCounter, &annos, pos)
|
||||
if err != nil {
|
||||
annosFromInterpolationError(&annos, err, metricName, pos)
|
||||
return enh.Out, annos
|
||||
}
|
||||
right, err := pickOrInterpolateRightHistogram(h, lastSampleIndex, rangeEnd, smoothed, isCounter, &annos, pos)
|
||||
if err != nil {
|
||||
annosFromInterpolationError(&annos, err, metricName, pos)
|
||||
return enh.Out, annos
|
||||
}
|
||||
|
||||
if !isCounter && (left.CounterResetHint != histogram.GaugeType || right.CounterResetHint != histogram.GaugeType) {
|
||||
annos.Add(annotations.NewNativeHistogramNotGaugeWarning(metricName, pos))
|
||||
}
|
||||
|
||||
// Copy right so that correctForCounterResetsHistogram can still call
|
||||
// right.DetectReset without observing mutations from subHistogramWithAnnotations.
|
||||
resultHistogram := right.Copy()
|
||||
if !subHistogramWithAnnotations(resultHistogram, left, &annos, metricName, pos) {
|
||||
return enh.Out, annos
|
||||
}
|
||||
|
||||
if isCounter {
|
||||
correction, newAnnos, ok := correctForCounterResetsHistogram(h, firstSampleIndex, lastSampleIndex, left, right, rangeStart, smoothed, 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 (
|
||||
|
|
@ -1432,6 +1708,16 @@ func funcSqrt(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNode
|
|||
return simpleFloatFunc(vectorVals, enh, math.Sqrt), nil
|
||||
}
|
||||
|
||||
// === max_of(a, b parser.ValueTypeScalar) Scalar ===
|
||||
func funcMaxOf(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
|
||||
return append(enh.Out, Sample{F: math.Max(vectorVals[0][0].F, vectorVals[1][0].F)}), nil
|
||||
}
|
||||
|
||||
// === min_of(a, b parser.ValueTypeScalar) Scalar ===
|
||||
func funcMinOf(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
|
||||
return append(enh.Out, Sample{F: math.Min(vectorVals[0][0].F, vectorVals[1][0].F)}), nil
|
||||
}
|
||||
|
||||
// === ln(Vector parser.ValueTypeVector) (Vector, Annotations) ===
|
||||
func funcLn(vectorVals []Vector, _ Matrix, _ parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
|
||||
return simpleFloatFunc(vectorVals, enh, math.Log), nil
|
||||
|
|
@ -1957,41 +2243,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
|
||||
|
|
@ -2249,7 +2555,7 @@ var FunctionCalls = map[string]FunctionCall{
|
|||
"day_of_week": funcDayOfWeek,
|
||||
"day_of_year": funcDayOfYear,
|
||||
"deg": funcDeg,
|
||||
"end": funcQueryContext,
|
||||
"end": nil, // Folded into NumberLiteral by foldQueryContextFunctions.
|
||||
"delta": funcDelta,
|
||||
"deriv": funcDeriv,
|
||||
"exp": funcExp,
|
||||
|
|
@ -2269,8 +2575,10 @@ var FunctionCalls = map[string]FunctionCall{
|
|||
"increase": funcIncrease,
|
||||
"info": nil,
|
||||
"irate": funcIrate,
|
||||
"max_of": funcMaxOf,
|
||||
"label_replace": nil, // evalLabelReplace not called via this map.
|
||||
"label_join": nil, // evalLabelJoin not called via this map.
|
||||
"min_of": funcMinOf,
|
||||
"ln": funcLn,
|
||||
"log10": funcLog10,
|
||||
"log2": funcLog2,
|
||||
|
|
@ -2289,7 +2597,7 @@ var FunctionCalls = map[string]FunctionCall{
|
|||
"present_over_time": funcPresentOverTime,
|
||||
"quantile_over_time": funcQuantileOverTime,
|
||||
"rad": funcRad,
|
||||
"range": funcQueryContext,
|
||||
"range": nil, // Folded into NumberLiteral by foldQueryContextFunctions.
|
||||
"rate": funcRate,
|
||||
"resets": funcResets,
|
||||
"round": funcRound,
|
||||
|
|
@ -2301,8 +2609,8 @@ var FunctionCalls = map[string]FunctionCall{
|
|||
"sort_desc": funcSortDesc,
|
||||
"sort_by_label": funcSortByLabel,
|
||||
"sort_by_label_desc": funcSortByLabelDesc,
|
||||
"start": funcQueryContext,
|
||||
"step": funcQueryContext,
|
||||
"start": nil, // Folded into NumberLiteral by foldQueryContextFunctions.
|
||||
"step": nil, // Folded into NumberLiteral by foldQueryContextFunctions.
|
||||
"sqrt": funcSqrt,
|
||||
"stddev_over_time": funcStddevOverTime,
|
||||
"stdvar_over_time": funcStdvarOverTime,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/prometheus/prometheus/model/histogram"
|
||||
"github.com/prometheus/prometheus/model/labels"
|
||||
"github.com/prometheus/prometheus/promql/parser/posrange"
|
||||
"github.com/prometheus/prometheus/util/annotations"
|
||||
"github.com/prometheus/prometheus/util/kahansum"
|
||||
)
|
||||
|
||||
|
|
@ -119,3 +120,59 @@ func TestInterpolate(t *testing.T) {
|
|||
require.Equal(t, test.expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterpolateHistograms(t *testing.T) {
|
||||
h1 := &histogram.FloatHistogram{Count: 1, Sum: 1, CounterResetHint: histogram.UnknownCounterReset}
|
||||
h2 := &histogram.FloatHistogram{Count: 3, Sum: 3, CounterResetHint: histogram.UnknownCounterReset}
|
||||
h2Reset := &histogram.FloatHistogram{Count: 1, Sum: 1, CounterResetHint: histogram.CounterReset}
|
||||
pos := posrange.PositionRange{}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
h1, h2 *histogram.FloatHistogram
|
||||
t1, t2, t int64
|
||||
isCounter bool
|
||||
wantCount float64
|
||||
}{
|
||||
{
|
||||
name: "exact match t1",
|
||||
h1: h1, h2: h2, t1: 0, t2: 20, t: 0,
|
||||
isCounter: false, wantCount: 1,
|
||||
},
|
||||
{
|
||||
name: "exact match t2",
|
||||
h1: h1, h2: h2, t1: 0, t2: 20, t: 20,
|
||||
isCounter: false, wantCount: 3,
|
||||
},
|
||||
{
|
||||
name: "midpoint no reset",
|
||||
h1: h1, h2: h2, t1: 0, t2: 20, t: 10,
|
||||
isCounter: false, wantCount: 2,
|
||||
},
|
||||
{
|
||||
name: "counter midpoint no reset",
|
||||
h1: h1, h2: h2, t1: 0, t2: 20, t: 10,
|
||||
isCounter: true, wantCount: 2,
|
||||
},
|
||||
{
|
||||
name: "counter midpoint with reset: scale from zero",
|
||||
h1: h1, h2: h2Reset, t1: 0, t2: 20, t: 10,
|
||||
// h2Reset * (10/20) = count:1 * 0.5 = 0.5.
|
||||
isCounter: true, wantCount: 0.5,
|
||||
},
|
||||
{
|
||||
name: "quarter point",
|
||||
h1: h1, h2: h2, t1: 0, t2: 20, t: 5,
|
||||
// h1 + (h2-h1)*0.25 = 1 + 2*0.25 = 1.5.
|
||||
isCounter: false, wantCount: 1.5,
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var annos annotations.Annotations
|
||||
result, err := interpolateHistograms(tc.h1, tc.t1, tc.h2, tc.t2, tc.t, tc.isCounter, &annos, pos)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.wantCount, result.Count)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,11 +263,23 @@ var Functions = map[string]*Function{
|
|||
Variadic: -1,
|
||||
ReturnType: ValueTypeVector,
|
||||
},
|
||||
"max_of": {
|
||||
Name: "max_of",
|
||||
ArgTypes: []ValueType{ValueTypeScalar, ValueTypeScalar},
|
||||
ReturnType: ValueTypeScalar,
|
||||
Experimental: true,
|
||||
},
|
||||
"last_over_time": {
|
||||
Name: "last_over_time",
|
||||
ArgTypes: []ValueType{ValueTypeMatrix},
|
||||
ReturnType: ValueTypeVector,
|
||||
},
|
||||
"min_of": {
|
||||
Name: "min_of",
|
||||
ArgTypes: []ValueType{ValueTypeScalar, ValueTypeScalar},
|
||||
ReturnType: ValueTypeScalar,
|
||||
Experimental: true,
|
||||
},
|
||||
"ln": {
|
||||
Name: "ln",
|
||||
ArgTypes: []ValueType{ValueTypeVector},
|
||||
|
|
|
|||
|
|
@ -159,6 +159,8 @@ START
|
|||
END
|
||||
STEP
|
||||
RANGE
|
||||
MAX_OF
|
||||
MIN_OF
|
||||
%token preprocessorEnd
|
||||
|
||||
// Counter reset hints.
|
||||
|
|
@ -183,7 +185,7 @@ START_METRIC_SELECTOR
|
|||
// Type definitions for grammar rules.
|
||||
%type <matchers> label_match_list
|
||||
%type <matcher> label_matcher
|
||||
%type <item> aggregate_op grouping_label match_op maybe_label metric_identifier unary_op at_modifier_preprocessors string_identifier counter_reset_hint min_max
|
||||
%type <item> aggregate_op grouping_label match_op maybe_label metric_identifier unary_op at_modifier_preprocessors string_identifier counter_reset_hint max_of_min_of
|
||||
%type <labels> label_set metric
|
||||
%type <lblList> label_set_list
|
||||
%type <label> label_set_item
|
||||
|
|
@ -526,6 +528,24 @@ function_call : IDENTIFIER function_call_body
|
|||
},
|
||||
}
|
||||
}
|
||||
| max_of_min_of function_call_body
|
||||
{
|
||||
fn, exist := getFunction($1.Val, yylex.(*parser).functions)
|
||||
if !exist{
|
||||
yylex.(*parser).addParseErrf($1.PositionRange(),"unknown function with name %q", $1.Val)
|
||||
}
|
||||
if fn != nil && fn.Experimental && !yylex.(*parser).options.EnableExperimentalFunctions {
|
||||
yylex.(*parser).addParseErrf($1.PositionRange(),"function %q is not enabled", $1.Val)
|
||||
}
|
||||
$$ = &Call{
|
||||
Func: fn,
|
||||
Args: $2.(Expressions),
|
||||
PosRange: posrange.PositionRange{
|
||||
Start: $1.PositionRange().Start,
|
||||
End: yylex.(*parser).lastClosing,
|
||||
},
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
function_call_body: LEFT_PAREN function_call_args RIGHT_PAREN
|
||||
|
|
@ -814,7 +834,7 @@ metric : metric_identifier label_set
|
|||
;
|
||||
|
||||
|
||||
metric_identifier: AVG | BOTTOMK | BY | COUNT | COUNT_VALUES | FILL | FILL_LEFT | FILL_RIGHT | GROUP | IDENTIFIER | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | QUANTILE | STDDEV | STDVAR | SUM | TOPK | WITHOUT | START | END | LIMITK | LIMIT_RATIO | STEP | RANGE | ANCHORED | SMOOTHED;
|
||||
metric_identifier: AVG | BOTTOMK | BY | COUNT | COUNT_VALUES | FILL | FILL_LEFT | FILL_RIGHT | GROUP | IDENTIFIER | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | QUANTILE | STDDEV | STDVAR | SUM | TOPK | WITHOUT | START | END | LIMITK | LIMIT_RATIO | STEP | RANGE | ANCHORED | SMOOTHED | MAX_OF | MIN_OF;
|
||||
|
||||
label_set : LEFT_BRACE label_set_list RIGHT_BRACE
|
||||
{ $$ = labels.New($2...) }
|
||||
|
|
@ -1072,7 +1092,7 @@ counter_reset_hint : UNKNOWN_COUNTER_RESET | COUNTER_RESET | NOT_COUNTER_RESET |
|
|||
aggregate_op : AVG | BOTTOMK | COUNT | COUNT_VALUES | GROUP | MAX | MIN | QUANTILE | STDDEV | STDVAR | SUM | TOPK | LIMITK | LIMIT_RATIO;
|
||||
|
||||
// Inside of grouping options label names can be recognized as keywords by the lexer. This is a list of keywords that could also be a label name.
|
||||
maybe_label : AVG | BOOL | BOTTOMK | BY | COUNT | COUNT_VALUES | GROUP | GROUP_LEFT | GROUP_RIGHT | FILL | FILL_LEFT | FILL_RIGHT | IDENTIFIER | IGNORING | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | ON | QUANTILE | STDDEV | STDVAR | SUM | TOPK | START | END | ATAN2 | LIMITK | LIMIT_RATIO | STEP | RANGE | ANCHORED | SMOOTHED;
|
||||
maybe_label : AVG | BOOL | BOTTOMK | BY | COUNT | COUNT_VALUES | GROUP | GROUP_LEFT | GROUP_RIGHT | FILL | FILL_LEFT | FILL_RIGHT | IDENTIFIER | IGNORING | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | ON | QUANTILE | STDDEV | STDVAR | SUM | TOPK | START | END | ATAN2 | LIMITK | LIMIT_RATIO | STEP | RANGE | ANCHORED | SMOOTHED | MAX_OF | MIN_OF;
|
||||
|
||||
unary_op : ADD | SUB;
|
||||
|
||||
|
|
@ -1178,7 +1198,7 @@ maybe_grouping_labels: /* empty */ { $$ = nil }
|
|||
offset_duration_expr : number_duration_literal
|
||||
{
|
||||
nl := $1.(*NumberLiteral)
|
||||
if nl.Val > 1<<63/1e9 || nl.Val < -(1<<63)/1e9 {
|
||||
if durationLiteralOutOfRange(nl.Val) {
|
||||
yylex.(*parser).addParseErrf(nl.PosRange, "duration out of range")
|
||||
$$ = &NumberLiteral{Val: 0}
|
||||
break
|
||||
|
|
@ -1191,7 +1211,7 @@ offset_duration_expr : number_duration_literal
|
|||
if $1.Typ == SUB {
|
||||
nl.Val *= -1
|
||||
}
|
||||
if nl.Val > 1<<63/1e9 || nl.Val < -(1<<63)/1e9 {
|
||||
if durationLiteralOutOfRange(nl.Val) {
|
||||
yylex.(*parser).addParseErrf($1.PositionRange(), "duration out of range")
|
||||
$$ = &NumberLiteral{Val: 0}
|
||||
break
|
||||
|
|
@ -1201,23 +1221,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 +1250,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 +1264,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
|
||||
| max_of_min_of 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
|
||||
| unary_op max_of_min_of LEFT_PAREN duration_expr COMMA duration_expr RIGHT_PAREN
|
||||
{
|
||||
$$ = &DurationExpr{
|
||||
de := &DurationExpr{
|
||||
Op: $1.Typ,
|
||||
StartPos: $1.Pos,
|
||||
EndPos: $6.PositionRange().End,
|
||||
|
|
@ -1263,30 +1293,22 @@ offset_duration_expr : number_duration_literal
|
|||
RHS: $6.(Expr),
|
||||
},
|
||||
}
|
||||
yylex.(*parser).experimentalDurationExpr(de)
|
||||
$$ = de
|
||||
}
|
||||
| unary_op LEFT_PAREN duration_expr RIGHT_PAREN %prec MUL
|
||||
{
|
||||
de := $3.(*DurationExpr)
|
||||
de.Wrapped = true
|
||||
if $1.Typ == SUB {
|
||||
$$ = &DurationExpr{
|
||||
Op: SUB,
|
||||
RHS: de,
|
||||
StartPos: $1.Pos,
|
||||
}
|
||||
break
|
||||
}
|
||||
$$ = $3
|
||||
$$ = yylex.(*parser).applyUnaryOpToDurationExpr($1, $3.(Node), true)
|
||||
}
|
||||
| duration_expr
|
||||
;
|
||||
|
||||
min_max: MIN | MAX ;
|
||||
max_of_min_of: MAX_OF | MIN_OF ;
|
||||
|
||||
duration_expr : number_duration_literal
|
||||
{
|
||||
nl := $1.(*NumberLiteral)
|
||||
if nl.Val > 1<<63/1e9 || nl.Val < -(1<<63)/1e9 {
|
||||
if durationLiteralOutOfRange(nl.Val) {
|
||||
yylex.(*parser).addParseErrf(nl.PosRange, "duration out of range")
|
||||
$$ = &NumberLiteral{Val: 0}
|
||||
break
|
||||
|
|
@ -1295,50 +1317,26 @@ duration_expr : number_duration_literal
|
|||
}
|
||||
| unary_op duration_expr %prec MUL
|
||||
{
|
||||
switch expr := $2.(type) {
|
||||
case *NumberLiteral:
|
||||
if $1.Typ == SUB {
|
||||
expr.Val *= -1
|
||||
}
|
||||
if expr.Val > 1<<63/1e9 || expr.Val < -(1<<63)/1e9 {
|
||||
yylex.(*parser).addParseErrf($1.PositionRange(), "duration out of range")
|
||||
$$ = &NumberLiteral{Val: 0}
|
||||
break
|
||||
}
|
||||
expr.PosRange.Start = $1.Pos
|
||||
$$ = expr
|
||||
break
|
||||
case *DurationExpr:
|
||||
if $1.Typ == SUB {
|
||||
$$ = &DurationExpr{
|
||||
Op: SUB,
|
||||
RHS: expr,
|
||||
StartPos: $1.Pos,
|
||||
}
|
||||
break
|
||||
}
|
||||
$$ = expr
|
||||
break
|
||||
default:
|
||||
yylex.(*parser).addParseErrf($1.PositionRange(), "expected number literal or duration expression")
|
||||
$$ = &NumberLiteral{Val: 0}
|
||||
break
|
||||
$$ = yylex.(*parser).applyUnaryOpToDurationExpr($1, $2.(Node), false)
|
||||
}
|
||||
}
|
||||
| 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 +1346,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,39 +1356,47 @@ 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
|
||||
{
|
||||
$$ = &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
|
||||
| max_of_min_of 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
|
||||
;
|
||||
|
||||
paren_duration_expr : LEFT_PAREN duration_expr RIGHT_PAREN
|
||||
{
|
||||
yylex.(*parser).experimentalDurationExpr($2.(Expr))
|
||||
if durationExpr, ok := $2.(*DurationExpr); ok {
|
||||
durationExpr.Wrapped = true
|
||||
$$ = durationExpr
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -143,10 +143,12 @@ var key = map[string]ItemType{
|
|||
"bool": BOOL,
|
||||
|
||||
// Preprocessors.
|
||||
"start": START,
|
||||
"end": END,
|
||||
"step": STEP,
|
||||
"range": RANGE,
|
||||
"start": START,
|
||||
"end": END,
|
||||
"step": STEP,
|
||||
"range": RANGE,
|
||||
"max_of": MAX_OF,
|
||||
"min_of": MIN_OF,
|
||||
}
|
||||
|
||||
var histogramDesc = map[string]ItemType{
|
||||
|
|
@ -499,15 +501,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':
|
||||
case isDurationKeywordStartChar(r):
|
||||
if l.scanDurationKeyword() {
|
||||
return lexStatements
|
||||
}
|
||||
|
|
@ -935,6 +937,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,
|
||||
"max_of": MAX_OF,
|
||||
"min_of": MIN_OF,
|
||||
}
|
||||
|
||||
// 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 +970,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 +1255,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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -336,7 +337,8 @@ func (p *parser) unexpected(context, expected string) {
|
|||
p.addParseErr(p.yyParser.lval.item.PositionRange(), errors.New(errMsg.String()))
|
||||
}
|
||||
|
||||
var errUnexpected = errors.New("unexpected error")
|
||||
// ErrUnexpected is returned when the parser recovers from a runtime panic.
|
||||
var ErrUnexpected = errors.New("unexpected error")
|
||||
|
||||
// recover is the handler that turns panics into returns from the top level of Parse.
|
||||
func (*parser) recover(errp *error) {
|
||||
|
|
@ -348,7 +350,7 @@ func (*parser) recover(errp *error) {
|
|||
buf = buf[:runtime.Stack(buf, false)]
|
||||
|
||||
fmt.Fprintf(os.Stderr, "parser panic: %v\n%s", e, buf)
|
||||
*errp = errUnexpected
|
||||
*errp = ErrUnexpected
|
||||
case e != nil:
|
||||
*errp = e.(error)
|
||||
}
|
||||
|
|
@ -1085,8 +1087,12 @@ func (p *parser) setAnchored(e Node) {
|
|||
p.addParseErrf(e.PositionRange(), "anchored and smoothed modifiers cannot be used together")
|
||||
}
|
||||
case *MatrixSelector:
|
||||
s.VectorSelector.(*VectorSelector).Anchored = true
|
||||
if s.VectorSelector.(*VectorSelector).Smoothed {
|
||||
vs, ok := s.VectorSelector.(*VectorSelector)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
vs.Anchored = true
|
||||
if vs.Smoothed {
|
||||
p.addParseErrf(e.PositionRange(), "anchored and smoothed modifiers cannot be used together")
|
||||
}
|
||||
case *SubqueryExpr:
|
||||
|
|
@ -1108,8 +1114,12 @@ func (p *parser) setSmoothed(e Node) {
|
|||
p.addParseErrf(e.PositionRange(), "anchored and smoothed modifiers cannot be used together")
|
||||
}
|
||||
case *MatrixSelector:
|
||||
s.VectorSelector.(*VectorSelector).Smoothed = true
|
||||
if s.VectorSelector.(*VectorSelector).Anchored {
|
||||
vs, ok := s.VectorSelector.(*VectorSelector)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
vs.Smoothed = true
|
||||
if vs.Anchored {
|
||||
p.addParseErrf(e.PositionRange(), "anchored and smoothed modifiers cannot be used together")
|
||||
}
|
||||
case *SubqueryExpr:
|
||||
|
|
@ -1192,6 +1202,51 @@ func (p *parser) getAtModifierVars(e Node) (**int64, *ItemType, *posrange.Pos, b
|
|||
return timestampp, preprocp, endPosp, true
|
||||
}
|
||||
|
||||
// durationLiteralOutOfRange reports whether val, interpreted as seconds, would
|
||||
// overflow a time.Duration (int64 nanoseconds).
|
||||
func durationLiteralOutOfRange(val float64) bool {
|
||||
return val > 1<<63/1e9 || val < -(1<<63)/1e9
|
||||
}
|
||||
|
||||
func (p *parser) experimentalDurationExpr(e Expr) {
|
||||
if !p.options.ExperimentalDurationExpr {
|
||||
p.addParseErrf(e.PositionRange(), "experimental duration expression is not enabled")
|
||||
}
|
||||
}
|
||||
|
||||
// applyUnaryOpToDurationExpr applies a unary operator to a duration expression
|
||||
// node, which may be a *DurationExpr or a *NumberLiteral. When wrapped is true
|
||||
// (parenthesised form), the Wrapped flag is set on *DurationExpr nodes.
|
||||
func (p *parser) applyUnaryOpToDurationExpr(op Item, expr Node, wrapped bool) Node {
|
||||
switch e := expr.(type) {
|
||||
case *DurationExpr:
|
||||
if wrapped {
|
||||
e.Wrapped = true
|
||||
}
|
||||
if op.Typ == SUB {
|
||||
return &DurationExpr{
|
||||
Op: SUB,
|
||||
RHS: e,
|
||||
StartPos: op.Pos,
|
||||
}
|
||||
}
|
||||
return e
|
||||
case *NumberLiteral:
|
||||
if op.Typ == SUB {
|
||||
e.Val *= -1
|
||||
}
|
||||
if durationLiteralOutOfRange(e.Val) {
|
||||
p.addParseErrf(op.PositionRange(), "duration out of range")
|
||||
return &NumberLiteral{Val: 0}
|
||||
}
|
||||
e.PosRange.Start = op.Pos
|
||||
return e
|
||||
default:
|
||||
p.addParseErrf(op.PositionRange(), "expected number literal or duration expression")
|
||||
return &NumberLiteral{Val: 0}
|
||||
}
|
||||
}
|
||||
|
||||
func MustLabelMatcher(mt labels.MatchType, name, val string) *labels.Matcher {
|
||||
m, err := labels.NewMatcher(mt, name, val)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1713,6 +1713,28 @@ var testExpr = []struct {
|
|||
PosRange: posrange.PositionRange{Start: 0, End: 14},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "foo offset +(5)",
|
||||
expected: &VectorSelector{
|
||||
Name: "foo",
|
||||
OriginalOffset: 5 * time.Second,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"),
|
||||
},
|
||||
PosRange: posrange.PositionRange{Start: 0, End: 15},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "foo offset -(5)",
|
||||
expected: &VectorSelector{
|
||||
Name: "foo",
|
||||
OriginalOffset: -5 * time.Second,
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"),
|
||||
},
|
||||
PosRange: posrange.PositionRange{Start: 0, End: 15},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: `http_requests{group="production"} + on(instance) group_left(job,instance) cpu_count{type="smp"}`,
|
||||
fail: true,
|
||||
|
|
@ -4610,7 +4632,7 @@ var testExpr = []struct {
|
|||
},
|
||||
},
|
||||
{
|
||||
input: `foo[max(step(),5s)]`,
|
||||
input: `foo[max_of(step(),5s)]`,
|
||||
expected: &MatrixSelector{
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "foo",
|
||||
|
|
@ -4620,83 +4642,83 @@ var testExpr = []struct {
|
|||
PosRange: posrange.PositionRange{Start: 0, End: 3},
|
||||
},
|
||||
RangeExpr: &DurationExpr{
|
||||
Op: MAX,
|
||||
Op: MAX_OF,
|
||||
LHS: &DurationExpr{
|
||||
Op: STEP,
|
||||
StartPos: 8,
|
||||
EndPos: 14,
|
||||
StartPos: 11,
|
||||
EndPos: 17,
|
||||
},
|
||||
RHS: &NumberLiteral{
|
||||
Val: 5,
|
||||
Duration: true,
|
||||
PosRange: posrange.PositionRange{Start: 15, End: 17},
|
||||
PosRange: posrange.PositionRange{Start: 18, End: 20},
|
||||
},
|
||||
StartPos: 4,
|
||||
EndPos: 18,
|
||||
EndPos: 21,
|
||||
},
|
||||
EndPos: 19,
|
||||
EndPos: 22,
|
||||
},
|
||||
},
|
||||
{
|
||||
input: `foo offset max(step(),5s)`,
|
||||
input: `foo offset max_of(step(),5s)`,
|
||||
expected: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"),
|
||||
},
|
||||
PosRange: posrange.PositionRange{Start: 0, End: 25},
|
||||
PosRange: posrange.PositionRange{Start: 0, End: 28},
|
||||
OriginalOffsetExpr: &DurationExpr{
|
||||
Op: MAX,
|
||||
Op: MAX_OF,
|
||||
LHS: &DurationExpr{
|
||||
Op: STEP,
|
||||
StartPos: 15,
|
||||
EndPos: 21,
|
||||
StartPos: 18,
|
||||
EndPos: 24,
|
||||
},
|
||||
RHS: &NumberLiteral{
|
||||
Val: 5,
|
||||
Duration: true,
|
||||
PosRange: posrange.PositionRange{Start: 22, End: 24},
|
||||
PosRange: posrange.PositionRange{Start: 25, End: 27},
|
||||
},
|
||||
StartPos: 11,
|
||||
EndPos: 25,
|
||||
EndPos: 28,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: `foo offset -min(5s,step()+8s)`,
|
||||
input: `foo offset -min_of(5s,step()+8s)`,
|
||||
expected: &VectorSelector{
|
||||
Name: "foo",
|
||||
LabelMatchers: []*labels.Matcher{
|
||||
MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"),
|
||||
},
|
||||
PosRange: posrange.PositionRange{Start: 0, End: 29},
|
||||
PosRange: posrange.PositionRange{Start: 0, End: 32},
|
||||
OriginalOffsetExpr: &DurationExpr{
|
||||
Op: SUB,
|
||||
RHS: &DurationExpr{
|
||||
Op: MIN,
|
||||
Op: MIN_OF,
|
||||
LHS: &NumberLiteral{
|
||||
Val: 5,
|
||||
Duration: true,
|
||||
PosRange: posrange.PositionRange{Start: 16, End: 18},
|
||||
PosRange: posrange.PositionRange{Start: 19, End: 21},
|
||||
},
|
||||
RHS: &DurationExpr{
|
||||
Op: ADD,
|
||||
LHS: &DurationExpr{
|
||||
Op: STEP,
|
||||
StartPos: 19,
|
||||
EndPos: 25,
|
||||
StartPos: 22,
|
||||
EndPos: 28,
|
||||
},
|
||||
RHS: &NumberLiteral{
|
||||
Val: 8,
|
||||
Duration: true,
|
||||
PosRange: posrange.PositionRange{Start: 26, End: 28},
|
||||
PosRange: posrange.PositionRange{Start: 29, End: 31},
|
||||
},
|
||||
},
|
||||
StartPos: 12,
|
||||
EndPos: 28,
|
||||
EndPos: 31,
|
||||
},
|
||||
StartPos: 11,
|
||||
EndPos: 28,
|
||||
EndPos: 31,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -4718,6 +4740,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{
|
||||
|
|
@ -4767,7 +4815,7 @@ var testExpr = []struct {
|
|||
},
|
||||
},
|
||||
{
|
||||
input: `foo[max(range(),5s)]`,
|
||||
input: `foo[max_of(range(),5s)]`,
|
||||
expected: &MatrixSelector{
|
||||
VectorSelector: &VectorSelector{
|
||||
Name: "foo",
|
||||
|
|
@ -4777,21 +4825,21 @@ var testExpr = []struct {
|
|||
PosRange: posrange.PositionRange{Start: 0, End: 3},
|
||||
},
|
||||
RangeExpr: &DurationExpr{
|
||||
Op: MAX,
|
||||
Op: MAX_OF,
|
||||
LHS: &DurationExpr{
|
||||
Op: RANGE,
|
||||
StartPos: 8,
|
||||
EndPos: 15,
|
||||
StartPos: 11,
|
||||
EndPos: 18,
|
||||
},
|
||||
RHS: &NumberLiteral{
|
||||
Val: 5,
|
||||
Duration: true,
|
||||
PosRange: posrange.PositionRange{Start: 16, End: 18},
|
||||
PosRange: posrange.PositionRange{Start: 19, End: 21},
|
||||
},
|
||||
StartPos: 4,
|
||||
EndPos: 19,
|
||||
EndPos: 22,
|
||||
},
|
||||
EndPos: 20,
|
||||
EndPos: 23,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -5282,6 +5330,29 @@ var testExpr = []struct {
|
|||
},
|
||||
},
|
||||
},
|
||||
// Anchored/smoothed on non-selector range must not panic.
|
||||
{
|
||||
input: "1[5m] smoothed",
|
||||
fail: true,
|
||||
errors: ParseErrors{
|
||||
{
|
||||
PositionRange: posrange.PositionRange{Start: 1, End: 5},
|
||||
Err: errors.New("ranges only allowed for vector selectors"),
|
||||
Query: "1[5m] smoothed",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
input: "1[5m] anchored",
|
||||
fail: true,
|
||||
errors: ParseErrors{
|
||||
{
|
||||
PositionRange: posrange.PositionRange{Start: 1, End: 5},
|
||||
Err: errors.New("ranges only allowed for vector selectors"),
|
||||
Query: "1[5m] anchored",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func makeInt64Pointer(val int64) *int64 {
|
||||
|
|
@ -5300,7 +5371,9 @@ func readable(s string) string {
|
|||
|
||||
func TestParseExpressions(t *testing.T) {
|
||||
optsParser := NewParser(Options{
|
||||
EnableExperimentalFunctions: true,
|
||||
EnableExperimentalFunctions: true,
|
||||
ExperimentalDurationExpr: true,
|
||||
EnableExtendedRangeSelectors: true,
|
||||
})
|
||||
|
||||
for _, test := range testExpr {
|
||||
|
|
@ -5308,7 +5381,7 @@ func TestParseExpressions(t *testing.T) {
|
|||
expr, err := optsParser.ParseExpr(test.input)
|
||||
|
||||
// Unexpected errors are always caused by a bug.
|
||||
require.NotEqual(t, err, errUnexpected, "unexpected error occurred")
|
||||
require.NotEqual(t, err, ErrUnexpected, "unexpected error occurred")
|
||||
|
||||
if !test.fail {
|
||||
require.NoError(t, err)
|
||||
|
|
@ -5962,7 +6035,7 @@ func TestParseSeries(t *testing.T) {
|
|||
metric, vals, err := testParser.ParseSeriesDesc(test.input)
|
||||
|
||||
// Unexpected errors are always caused by a bug.
|
||||
require.NotEqual(t, err, errUnexpected, "unexpected error occurred")
|
||||
require.NotEqual(t, err, ErrUnexpected, "unexpected error occurred")
|
||||
|
||||
if !test.fail {
|
||||
require.NoError(t, err)
|
||||
|
|
@ -5979,7 +6052,7 @@ func TestRecoverParserRuntime(t *testing.T) {
|
|||
var err error
|
||||
|
||||
defer func() {
|
||||
require.Equal(t, errUnexpected, err)
|
||||
require.Equal(t, ErrUnexpected, err)
|
||||
}()
|
||||
defer p.recover(&err)
|
||||
// Cause a runtime panic.
|
||||
|
|
@ -6057,6 +6130,7 @@ func TestParseCustomFunctions(t *testing.T) {
|
|||
func TestNewParser(t *testing.T) {
|
||||
p := NewParser(Options{
|
||||
EnableExperimentalFunctions: true,
|
||||
ExperimentalDurationExpr: true,
|
||||
})
|
||||
|
||||
// ParseExpr should work.
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ func (node *BinaryExpr) getMatchingStr() string {
|
|||
}
|
||||
|
||||
if vm.FillValues.LHS != nil || vm.FillValues.RHS != nil {
|
||||
if vm.FillValues.LHS == vm.FillValues.RHS {
|
||||
if vm.FillValues.LHS != nil && vm.FillValues.RHS != nil && *vm.FillValues.LHS == *vm.FillValues.RHS {
|
||||
matching += fmt.Sprintf(" fill (%v)", *vm.FillValues.LHS)
|
||||
} else {
|
||||
if vm.FillValues.LHS != nil {
|
||||
|
|
@ -205,14 +205,14 @@ func (node *DurationExpr) writeTo(b *bytes.Buffer) {
|
|||
b.WriteString("step()")
|
||||
case node.Op == RANGE:
|
||||
b.WriteString("range()")
|
||||
case node.Op == MIN:
|
||||
b.WriteString("min(")
|
||||
case node.Op == MIN_OF:
|
||||
b.WriteString("min_of(")
|
||||
b.WriteString(node.LHS.String())
|
||||
b.WriteString(", ")
|
||||
b.WriteString(node.RHS.String())
|
||||
b.WriteByte(')')
|
||||
case node.Op == MAX:
|
||||
b.WriteString("max(")
|
||||
case node.Op == MAX_OF:
|
||||
b.WriteString("max_of(")
|
||||
b.WriteString(node.LHS.String())
|
||||
b.WriteString(", ")
|
||||
b.WriteString(node.RHS.String())
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
|
||||
func TestExprString(t *testing.T) {
|
||||
optsParser := NewParser(Options{
|
||||
ExperimentalDurationExpr: true,
|
||||
EnableExtendedRangeSelectors: true,
|
||||
EnableBinopFillModifiers: true,
|
||||
})
|
||||
|
|
@ -129,6 +130,10 @@ func TestExprString(t *testing.T) {
|
|||
in: `a + fill_left(-23) fill_right(42) b`,
|
||||
out: `a + fill_left (-23) fill_right (42) b`,
|
||||
},
|
||||
{
|
||||
in: `a + fill_left(5) fill_right(5) b`,
|
||||
out: `a + fill (5) b`,
|
||||
},
|
||||
{
|
||||
in: `a + on(b) group_left fill(-23) c`,
|
||||
out: `a + on (b) group_left () fill (-23) c`,
|
||||
|
|
@ -269,22 +274,22 @@ func TestExprString(t *testing.T) {
|
|||
out: "foo offset (5 * 2)",
|
||||
},
|
||||
{
|
||||
in: "foo offset +min(10s, 20s)",
|
||||
out: "foo offset min(10s, 20s)",
|
||||
in: "foo offset +min_of(10s, 20s)",
|
||||
out: "foo offset min_of(10s, 20s)",
|
||||
},
|
||||
{
|
||||
in: "foo offset -min(10s, 20s)",
|
||||
in: "foo offset -min_of(10s, 20s)",
|
||||
},
|
||||
{
|
||||
in: "foo offset -min(10s, +max(step() ^ 2, 2))",
|
||||
out: "foo offset -min(10s, max(step() ^ 2, 2))",
|
||||
in: "foo offset -min_of(10s, +max_of(step() ^ 2, 2))",
|
||||
out: "foo offset -min_of(10s, max_of(step() ^ 2, 2))",
|
||||
},
|
||||
{
|
||||
in: "foo[200-min(-step()^+step(),1)]",
|
||||
out: "foo[200 - min(-step() ^ step(), 1)]",
|
||||
in: "foo[200-min_of(-step()^+step(),1)]",
|
||||
out: "foo[200 - min_of(-step() ^ step(), 1)]",
|
||||
},
|
||||
{
|
||||
in: "foo[200 - min(step() + 10s, -max(step() ^ 2, 3))]",
|
||||
in: "foo[200 - min_of(step() + 10s, -max_of(step() ^ 2, 3))]",
|
||||
},
|
||||
{
|
||||
in: "foo[range()]",
|
||||
|
|
@ -299,7 +304,7 @@ func TestExprString(t *testing.T) {
|
|||
in: "foo offset -range()",
|
||||
},
|
||||
{
|
||||
in: "foo[max(range(), 5s)]",
|
||||
in: "foo[max_of(range(), 5s)]",
|
||||
},
|
||||
{
|
||||
in: `predict_linear(foo[1h], 3000)`,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,13 +167,13 @@ eval range from 50s to 60s step 10s count_over_time(metric1_total[1+(STep()-5)*2
|
|||
eval range from 50s to 60s step 5s count_over_time(metric1_total[step()+1])
|
||||
{} 6 6 6
|
||||
|
||||
eval range from 50s to 60s step 5s count_over_time(metric1_total[min(step()+1,1h)])
|
||||
eval range from 50s to 60s step 5s count_over_time(metric1_total[min_of(step()+1,1h)])
|
||||
{} 6 6 6
|
||||
|
||||
eval range from 50s to 60s step 5s count_over_time(metric1_total[max(min(step()+1,1h),1ms)])
|
||||
eval range from 50s to 60s step 5s count_over_time(metric1_total[max_of(min_of(step()+1,1h),1ms)])
|
||||
{} 6 6 6
|
||||
|
||||
eval range from 50s to 60s step 5s count_over_time(metric1_total[((max(min((step()+1),((1h))),1ms)))])
|
||||
eval range from 50s to 60s step 5s count_over_time(metric1_total[((max_of(min_of((step()+1),((1h))),1ms)))])
|
||||
{} 6 6 6
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset STEP()
|
||||
|
|
@ -200,31 +200,31 @@ eval range from 50s to 60s step 5s metric1_total offset (STEP()/10)
|
|||
eval range from 50s to 60s step 5s metric1_total offset (step())
|
||||
metric1_total{} 45 50 55
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset min(step(), 1s)
|
||||
eval range from 50s to 60s step 5s metric1_total offset min_of(step(), 1s)
|
||||
metric1_total{} 49 54 59
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset min(step(), 1s)+8000
|
||||
eval range from 50s to 60s step 5s metric1_total offset min_of(step(), 1s)+8000
|
||||
{} 8049 8054 8059
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset -min(step(), 1s)+8000
|
||||
eval range from 50s to 60s step 5s metric1_total offset -min_of(step(), 1s)+8000
|
||||
{} 8051 8056 8061
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset -(min(step(), 1s))+8000
|
||||
eval range from 50s to 60s step 5s metric1_total offset -(min_of(step(), 1s))+8000
|
||||
{} 8051 8056 8061
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset -min(step(), 1s)^0
|
||||
eval range from 50s to 60s step 5s metric1_total offset -min_of(step(), 1s)^0
|
||||
{} 1 1 1
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset +min(step(), 1s)^0
|
||||
eval range from 50s to 60s step 5s metric1_total offset +min_of(step(), 1s)^0
|
||||
{} 1 1 1
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset min(step(), 1s)^0
|
||||
eval range from 50s to 60s step 5s metric1_total offset min_of(step(), 1s)^0
|
||||
{} 1 1 1
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset max(3s,min(step(), 1s))+8000
|
||||
eval range from 50s to 60s step 5s metric1_total offset max_of(3s,min_of(step(), 1s))+8000
|
||||
{} 8047 8052 8057
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset -(min(step(), 2s)-5)+8000
|
||||
eval range from 50s to 60s step 5s metric1_total offset -(min_of(step(), 2s)-5)+8000
|
||||
{} 8047 8052 8057
|
||||
|
||||
# Test range() function - resolves to query range (end - start).
|
||||
|
|
@ -238,7 +238,7 @@ eval range from 50s to 60s step 5s count_over_time(metric1_total[range()])
|
|||
eval range from 50s to 60s step 5s metric1_total offset range()
|
||||
metric1_total{} 40 45 50
|
||||
|
||||
eval range from 50s to 60s step 5s metric1_total offset min(range(), 8s)
|
||||
eval range from 50s to 60s step 5s metric1_total offset min_of(range(), 8s)
|
||||
metric1_total{} 42 47 52
|
||||
|
||||
clear
|
||||
|
|
|
|||
254
promql/promqltest/testdata/extended_vectors.test
vendored
254
promql/promqltest/testdata/extended_vectors.test
vendored
|
|
@ -457,3 +457,257 @@ 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).
|
||||
# hist_counter samples have no GaugeType hint so a not-a-gauge warning is emitted.
|
||||
eval instant at 50s histogram_count(delta(hist_counter[1m] smoothed))
|
||||
expect warn msg: PromQL warning: this native histogram metric is not a gauge: "hist_counter"
|
||||
{} 3.333333333333333
|
||||
|
||||
# Anchored rate at 50s: left=count:1 (t=0), right=count:4 (t=45), rate=3/60.
|
||||
eval instant at 50s histogram_count(rate(hist_counter[1m] anchored))
|
||||
{} 0.05
|
||||
|
||||
# Anchored delta (non-counter) at 50s: same result as anchored increase but
|
||||
# hist_counter samples have no GaugeType hint so a not-a-gauge warning is emitted.
|
||||
eval instant at 50s histogram_count(delta(hist_counter[1m] anchored))
|
||||
expect warn msg: PromQL warning: this native histogram metric is not a gauge: "hist_counter"
|
||||
{} 3
|
||||
|
||||
# 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
|
||||
|
||||
# At t=110s, no next sample; carry forward the last value (count:8 at t=105).
|
||||
eval instant at 110s histogram_count(hist_counter smoothed)
|
||||
{} 8
|
||||
|
||||
# Range eval for smoothed rate: verify per-step boundary handling.
|
||||
# hist_counter increments count:1 and sum:1 every 15s starting at t=0.
|
||||
# rate(hist_counter[1m] smoothed) at each step computes increase/60.
|
||||
# t=0: left=right=count:1, increase=0, rate=0.
|
||||
# t=15: left=count:1, right=count:2 (exact), increase=1, rate=1/60.
|
||||
# t=30: left=count:1, right=count:3 (exact), increase=2, rate=2/60.
|
||||
# t=45: left=count:1, right=count:4 (exact), increase=3, rate=3/60.
|
||||
# t=60: left=count:1, right=count:5 (exact), increase=4, rate=4/60.
|
||||
eval range from 0s to 60s step 15s histogram_count(rate(hist_counter[1m] smoothed))
|
||||
{} 0 0.016666666666666666 0.03333333333333333 0.05 0.06666666666666667
|
||||
|
||||
# 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
|
||||
|
||||
# Anchored increase with reset at last sample (T < rangeEnd): the reset hint on
|
||||
# h[2] must not self-detect when right is a direct copy of h[2].
|
||||
# Float reference (5 10 3): increase = 10 - 5 + 10 - 3? No: right - left + correction.
|
||||
# left=5 right=3 correction=h[1]=10 → 8. Bug returns 11 (adds h[2]=3 twice).
|
||||
clear
|
||||
load 30s
|
||||
anchored_reset_at_end {{schema:0 sum:5 count:5 buckets:[5]}} {{schema:0 sum:10 count:10 buckets:[10]}} {{schema:0 sum:3 count:3 buckets:[3] counter_reset_hint:reset}}
|
||||
|
||||
eval instant at 70s histogram_count(increase(anchored_reset_at_end[70s] anchored))
|
||||
{} 8
|
||||
|
||||
# Anchored increase with only two samples, second is a reset at rangeEnd.
|
||||
# The two-sample case must still apply the reset correction even though the
|
||||
# inner slice is empty after excluding both boundary samples.
|
||||
# Float reference: right - left + correction = 3 - 5 + 5 = 3.
|
||||
clear
|
||||
load 30s
|
||||
anchored_two_sample_reset {{schema:0 sum:5 count:5 buckets:[5]}} {{schema:0 sum:3 count:3 buckets:[3] counter_reset_hint:reset}}
|
||||
|
||||
eval instant at 30s histogram_count(increase(anchored_two_sample_reset[30s] anchored))
|
||||
{} 3
|
||||
|
||||
# Smoothed increase where the left interpolation crosses the first reset and a
|
||||
# second reset immediately follows the skipped sample. The correction must be
|
||||
# taken against h[firstSampleIndex+1] (count=5), not the interpolated left
|
||||
# (count=0.5). Float reference: 5.5.
|
||||
clear
|
||||
load 10s
|
||||
smoothed_double_reset {{schema:0 sum:10 count:10 buckets:[10]}} {{schema:0 sum:5 count:5 buckets:[5] counter_reset_hint:reset}} {{schema:0 sum:2 count:2 buckets:[2] counter_reset_hint:reset}} {{schema:0 sum:4 count:4 buckets:[4]}}
|
||||
|
||||
eval instant at 15s histogram_count(increase(smoothed_double_reset[14s] smoothed))
|
||||
{} 5.5
|
||||
|
||||
# Two-sample smoothed window where both left and right are interpolated from the
|
||||
# same reset. The left interpolation already accounts for the reset, so no
|
||||
# correction should be applied. Float reference: right-left = h[1].Mul(0.75) -
|
||||
# h[1].Mul(0.25) = h[1].Mul(0.5) = count 2.5. The first > last+1 early-return
|
||||
# in correctForCounterResetsHistogram prevents double-counting this case.
|
||||
clear
|
||||
load 20s
|
||||
smoothed_two_sample_both_interp {{schema:0 sum:10 count:10 buckets:[10]}} {{schema:0 sum:5 count:5 buckets:[5] counter_reset_hint:reset}}
|
||||
|
||||
eval instant at 15s histogram_count(increase(smoothed_two_sample_both_interp[10s] smoothed))
|
||||
{} 2.5
|
||||
|
||||
# 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"
|
||||
|
||||
# Smoothed rate where the RIGHT boundary interpolation crosses a counter reset.
|
||||
# Samples: t=0 count:5, t=10 count:10, t=20 count:3 (reset).
|
||||
# At t=15s, range=10s: rangeStart=5s, rangeEnd=15s.
|
||||
# left: interpolate(t=0 count:5, t=10 count:10, t=5s) = count:5+(count:5*0.5) = count:7.5.
|
||||
# right: interpolate(t=10 count:10, t=20 count:3 reset, t=15s) → reset path →
|
||||
# count:3 * 0.5 = count:1.5 (CounterResetHint=reset inherited).
|
||||
# Inner samples: h[t=10 count:10]. h[10].DetectReset(left=7.5)? no (10>7.5).
|
||||
# right.DetectReset(prev=count:10)? yes (reset hint). correction=count:10.
|
||||
# increase = count:1.5 - count:7.5 + count:10 = count:4.
|
||||
# rate = count:4/10 = 0.4.
|
||||
clear
|
||||
load 10s
|
||||
right_boundary_reset {{schema:0 sum:5 count:5 buckets:[5]}} {{schema:0 sum:10 count:10 buckets:[10]}} {{schema:0 sum:3 count:3 buckets:[3] counter_reset_hint:reset}}
|
||||
|
||||
eval instant at 15s histogram_count(rate(right_boundary_reset[10s] smoothed))
|
||||
{} 0.4
|
||||
|
|
|
|||
15
promql/promqltest/testdata/fill-modifier.test
vendored
15
promql/promqltest/testdata/fill-modifier.test
vendored
|
|
@ -309,6 +309,21 @@ eval range from 0 to 20m step 5m intermittent_left + fill_left(0) intermittent_r
|
|||
{label="b"} 100 _ 300 _ 500
|
||||
{label="c"} 1000 _ _ 4000 5000
|
||||
|
||||
# Regression test: group_left fill_left in a range query must apply fill values
|
||||
# at every timestep, even when the RHS sigOrd was matched at a previous timestep.
|
||||
# resetMatchedSigs previously used clear() which left non-nil empty maps, causing
|
||||
# the fill-LHS path to incorrectly skip unmatched RHS samples on subsequent timesteps.
|
||||
clear
|
||||
|
||||
load 5m
|
||||
matched_lhs{key="a"} 1 _ 3
|
||||
matched_rhs{key="a"} 10 20 30
|
||||
matched_rhs{key="b"} 100 200 300
|
||||
|
||||
eval range from 0 to 10m step 5m matched_lhs + on(key) group_left fill_left(0) matched_rhs
|
||||
{key="a"} 11 20 33
|
||||
{key="b"} 100 200 300
|
||||
|
||||
# ---------- fill with vectors where one side is empty ----------
|
||||
|
||||
clear
|
||||
|
|
|
|||
52
promql/promqltest/testdata/functions.test
vendored
52
promql/promqltest/testdata/functions.test
vendored
|
|
@ -2187,3 +2187,55 @@ eval range from 0s to 9s step 3s metric_for_at @ start()
|
|||
|
||||
eval range from 1s to 9s step 2s metric_for_at @ end()
|
||||
{__name__="metric_for_at"} 10 10 10 10 10
|
||||
|
||||
# Tests for min_of() and max_of() scalar functions.
|
||||
|
||||
# min_of(a, b) returns math.Min(a, b).
|
||||
# max_of(a, b) returns math.Max(a, b).
|
||||
|
||||
# Basic literal comparisons.
|
||||
eval instant at 0s min_of(3, 5)
|
||||
3
|
||||
|
||||
eval instant at 0s min_of(5, 3)
|
||||
3
|
||||
|
||||
eval instant at 0s max_of(3, 5)
|
||||
5
|
||||
|
||||
eval instant at 0s max_of(5, 3)
|
||||
5
|
||||
|
||||
# Equal values.
|
||||
eval instant at 0s min_of(4, 4)
|
||||
4
|
||||
|
||||
eval instant at 0s max_of(4, 4)
|
||||
4
|
||||
|
||||
# Negative values.
|
||||
eval instant at 0s min_of(-2, -5)
|
||||
-5
|
||||
|
||||
eval instant at 0s max_of(-2, -5)
|
||||
-2
|
||||
|
||||
# Zero and positive.
|
||||
eval instant at 0s min_of(0, 1)
|
||||
0
|
||||
|
||||
eval instant at 0s max_of(0, 1)
|
||||
1
|
||||
|
||||
# NaN propagation: any NaN input yields NaN.
|
||||
eval instant at 0s min_of(NaN, 3)
|
||||
NaN
|
||||
|
||||
eval instant at 0s min_of(3, NaN)
|
||||
NaN
|
||||
|
||||
eval instant at 0s max_of(NaN, 3)
|
||||
NaN
|
||||
|
||||
eval instant at 0s max_of(3, NaN)
|
||||
NaN
|
||||
|
|
|
|||
|
|
@ -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.)
|
||||
|
|
|
|||
10
promql/promqltest/testdata/start_timestamps.test
vendored
10
promql/promqltest/testdata/start_timestamps.test
vendored
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -505,7 +505,7 @@ func (ssi *storageSeriesIterator) AtT() int64 {
|
|||
return ssi.currT
|
||||
}
|
||||
|
||||
// TODO(krajorama): implement AtST.
|
||||
// TODO(krajorama,ywwg): implement AtST.
|
||||
func (*storageSeriesIterator) AtST() int64 {
|
||||
return 0
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue