Skip to content

PMM-14678 Rework vmagent remote-write routing - #5887

Merged
4nte merged 26 commits into
mainfrom
PMM-14678-vmagent-write-paths
Sep 28, 2026
Merged

4nte merged 26 commits into
mainfrom
PMM-14678-vmagent-write-paths

Conversation

@4nte

@4nte 4nte commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Ticket number: PMM-14678

Feature build: Percona-Lab/pmm-submodules#4556

Problem

In PMM HA, PMM Server told every PMM Client vmagent to write metrics to the in-cluster vmauth address (PMM_VM_URL). Clients outside the cluster cannot reach it, so services added with pmm-admin showed UNSPECIFIED status and empty dashboards while QAN, which rides the gRPC channel, kept working.

Change

The remote-write configuration is selected once, by deployment mode, and the two paths are independent:

  • Standalone (vmagent_standalone.go): unchanged routing. Internal VictoriaMetrics: clients write through PMM Server with their own PMM credentials. External VictoriaMetrics (PMM_VM_URL): clients and the server's own agent write to it directly.
  • HA (vmagent_ha.go): every write carries the VictoriaMetrics credential from PMM_VM_URL; only the URL differs. Clients write to the PMM Server address they already use, and the pmm-ha chart's HAProxy routes /victoriametrics/api/v1/write to vmauth (chart PR below). The server's own agent, which runs inside the cluster, writes to vmauth directly. PMM Server pods are not on the metrics write path; vmproxy stays a read-path component.

A single deployment-agnostic builder applies the operator's VMAGENT_* environment on top with two rules: an injected variable wins over PMM's default of the same name (the documented passthrough), and PMM's default credential is emitted only when the operator injected neither VMAGENT_remoteWrite_url nor a credential of their own (any half of a basic-auth pair, a bearer token or an OAuth2 client). An endpoint PMM did not choose never receives a credential PMM derived, half an injected pair is not completed with PMM's other half, and PMM's pair is never combined with a bearer token or OAuth2 client, which vmagent refuses to start with; custom headers and a client TLS certificate compose with basic auth and leave PMM's pair in place. An empty VMAGENT_* variable is ignored with a startup warning, because vmagent cannot use an empty value (an empty URL or log level stops it, an empty credential disables authentication). Startup validation rejects an injected VMAGENT_remoteWrite_url that does not parse, since vmagent exits on it, warns when a URL is injected without credentials or when only half of a basic-auth pair is set, and stays quiet when the URL carries userinfo or another vmagent authentication method is set.

Credentials reach vmagent through its environment only: no longer inside the write URL and no longer as -remoteWrite.basicAuth.* flags (VMAgentArgs() removed), so the documented VMAGENT_remoteWrite_basicAuth_* override works in every mode.

PMM_VM_URL is validated once at startup (models.ParseVictoriaMetricsURL): it must be an http or https URL with a host, so a scheme-less value fails fast instead of silently truncating the write URL. In HA, pmm-managed also warns when PMM_VM_URL carries no credentials and nothing is injected (every client write would get 401), and when HA runs against the built-in VictoriaMetrics; a PMM_VM_URL that carries only a username or only a password is reported too, and the HA startup line describes the write path actually configured. The debug dump of SetStateRequest masks env values whose key names a password, secret, or token, whatever characters the key contains, and startup environment tracing redacts URL userinfo, scheme-less values included, so the VictoriaMetrics password no longer appears in logs.

Behavior relative to main:

Agent main this PR
standalone, internal VM, clients proxy URL, own PMM credentials unchanged
standalone, external VM, clients and built-in agent direct; credentials in URL, args and env direct; credentials in env only
HA, clients direct to in-cluster vmauth (unreachable from outside), VM credentials {{.server_url}}/victoriametrics/api/v1/write via HAProxy, same VM credentials
HA, built-in agents direct to vmauth unchanged
any, injected VMAGENT_remoteWrite_url without credentials PMM's or the VM's credential forwarded to the injected endpoint no credential, startup warning
any, half of a basic-auth pair injected completed with PMM's other half, a pair that authenticates nowhere the lone half is sent alone, startup warning
any, bearer token or OAuth2 client injected sent alongside PMM's basic-auth pair; vmagent refuses to start PMM's pair withheld
any, empty VMAGENT_* variable forwarded; vmagent exits on an empty URL or log level ignored, startup warning

Chart dependency

Requires the percona-helm-charts change that adds the HAProxy route and renames the secret keys to PMM_HA_VM_USERNAME / PMM_HA_VM_PASSWORD: percona/percona-helm-charts#952. Upgrade the chart before PMM Server: a PMM Server with this change behind an older chart gets 401 for every client write (the pods reject the VictoriaMetrics credential). The chart README and the docs PR document the order; pmm-managed logs the requirement once when HA is enabled.

Documentation

User documentation for this change is in #5952 against doc-3.10.0, because docs merge ahead of the code: the VictoriaMetrics reference (PMM_VM_URL with and without credentials, VMAGENT_remoteWrite_url), the vmagent environment variables, and the HA guide (client write path through HAProxy, renamed pmm-secret keys, chart-first upgrade order). This PR carries no documentation changes.

Verification

  • Unit: 117 test cases in the vmagent suites in managed/services/agents (vmagent_test.go, vmagent_standalone_test.go, vmagent_ha_test.go, vmagent_golden_test.go, state_test.go), plus new tests in managed/utils/envvars, managed/models, and utils/logger; all four packages pass with -race. The golden test pins every rendered configuration as literal strings, and mutation checks with go test -overlay (typo in the proxy URL, partial-credential leak, HA client routed direct, built-in agent routed via the proxy, warning ignoring missing credentials, log leaking userinfo, error echoing the URL) all fail the suite.
  • Live, standalone (percona/pmm-server:3.9.1 base with main's nginx config and this pmm-managed): ten cells covering internal VM, external VM with and without auth, and every injection variant (credentials only, URL only, URL + credentials, URL + {{.server_*}} templates). Rendered env matches the design in every cell; the warning fires only in the URL-only cells.
  • Live, HA (dedicated kind cluster, chart from the chart PR): external client with no route to any cluster address and in-cluster client both land metrics, all nodes and services STATUS_UP; HAProxy's vmauth backend served 2600+ writes, all 2xx; zero write requests reached any pod's nginx or vmproxy; the three built-in agents write to vmauth directly (1000+ requests each, all 2xx); leader failover left writes uninterrupted; the escape hatch (injected vmauth URL + credentials) and the published-chart mismatch (401 at the pods) behaved as documented.

Supersedes #5581, whose review findings are all addressed here (vmproxy read-only, per-scenario paths, no dropInjectedAuth, credential withholding, env-only credentials, state.go wiring test).

4nte added 3 commits September 4, 2026 14:29
In HA, PMM Server told every PMM Client vmagent to write to the
in-cluster vmauth address, which clients outside the cluster cannot
reach: services added with pmm-admin showed no dashboard data while
QAN kept working (PMM-14678, PMM-14705).

Select the remote-write configuration once, by deployment mode, and
keep the two paths independent:

- Standalone: unchanged routing. Internal VictoriaMetrics: clients
  write through PMM Server with their own PMM credentials. External
  VictoriaMetrics: clients and the server's own agent write to
  PMM_VM_URL directly.
- HA: every write carries the VictoriaMetrics credential from
  PMM_VM_URL; only the URL differs. Clients write to the PMM Server
  address they already use, which the pmm-ha chart's HAProxy routes
  to vmauth (chart change shipped alongside). The server's own agent,
  which runs inside the cluster, writes to vmauth directly.

Credentials now reach vmagent through its environment only: they are
no longer embedded in the write URL or passed as command-line flags,
so an operator's VMAGENT_remoteWrite_basicAuth_* override works in
every mode. PMM's default credential belongs to PMM's default URL:
when an operator injects VMAGENT_remoteWrite_url, no default
credential is attached to it.

The deployment flags are computed in one helper on StateUpdater and
covered by a unit test; a golden test pins the complete environment
for every deployment shape as literal strings; pmm-managed logs the
chart requirement once when HA is enabled.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
VMAGENT_remoteWrite_url redirects every PMM Client's metric writes,
and PMM sends none of its own credentials to an endpoint it did not
choose. Warn at startup when the URL is injected without
VMAGENT_remoteWrite_basicAuth_*, so the resulting unauthenticated
writes are not silent.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
Describe PMM_VM_URL with and without credentials, the precedence of
VMAGENT_remoteWrite_basicAuth_* over URL credentials, and the global
VMAGENT_remoteWrite_url override. In the HA guide, explain how client
metrics reach VictoriaMetrics through HAProxy, the renamed secret
keys, the chart-first upgrade order, and drop the PMM-14705 known
issue.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
@codecov

codecov Bot commented Sep 4, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.81395% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.33%. Comparing base (31318c7) to head (0117b41).
⚠️ Report is 228 commits behind head on main.

Files with missing lines Patch % Lines
managed/cmd/pmm-managed/main.go 0.00% 6 Missing ⚠️
managed/models/victoriametrics_params.go 95.74% 2 Missing ⚠️
managed/services/agents/state.go 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5887      +/-   ##
==========================================
+ Coverage   43.59%   51.33%   +7.73%     
==========================================
  Files         415      420       +5     
  Lines       43134    39531    -3603     
==========================================
+ Hits        18804    20292    +1488     
+ Misses      22454    19239    -3215     
+ Partials     1876        0    -1876     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

4nte added 2 commits September 4, 2026 16:46
Follow-up to the review of the vmagent remote-write paths.

PMM_VM_URL is parsed and validated in one place,
models.ParseVictoriaMetricsURL: it must be an http or https URL with a
host. A scheme-less value now fails at startup instead of silently
truncating the remote-write URL handed to every vmagent. vmAgentConfig
returns an error for a URL it cannot parse, and the error never echoes
the URL because the URL may carry a password.

In HA, pmm-managed warns at startup when PMM_VM_URL carries no
credentials and no VMAGENT_remoteWrite_basicAuth_* is injected, since
every PMM Client write would then be rejected with 401, and when HA is
enabled with the built-in VictoriaMetrics.

Environment validation rejects an empty VMAGENT_remoteWrite_url, warns
when only one half of the basic-auth pair accompanies an injected URL,
and stays quiet when the URL carries userinfo or another vmagent auth
method is set. The URL-only warning no longer suggests a fix that is
wrong in HA.

Also drop the unused URLFor from the VictoriaMetrics params interface,
log the agent id and the injected URL (without userinfo) at debug level,
correct comments that misdescribed the built-in agent's route, remove
inert VMAGENT_* rows from the docs, and delete a dead gosec exclusion.

Tests clear VMAGENT_* from the process before running, cover the new
error and warning paths, and add golden rows for an injected URL with
one credential, an HA client without credentials, and a password-only
external VictoriaMetrics.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
The env entries of an AgentProcess are marked REDACT_TYPE_DSN, which
only masks credentials inside URL userinfo. vmagent now receives its
remote-write password as a plain KEY=value entry
(VMAGENT_remoteWrite_basicAuth_password), so the VictoriaMetrics
password reached pmm-managed's debug dump of SetStateRequest in clear
text. MaskDSN now also masks the value of any KEY=value entry whose key
names a password, secret, or token.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
@4nte

4nte commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Sep 4, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Sep 4, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 0ae0456e-f16b-442b-9e9f-9511335d4b03

📥 Commits

Reviewing files that changed from the base of the PR and between a5aba05 and 9fb2be6.

📒 Files selected for processing (2)
  • utils/logger/protobuf.go
  • utils/logger/protobuf_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • percona/pmm-qa (manual)
  • percona/pmm (manual)

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.


Walkthrough

The change centralizes VictoriaMetrics URL parsing and validation, including credential-safe errors and parsed URL copies. Vmagent configuration now selects standalone or HA routing from deployment context. URL credentials are separated from endpoints, and injected authentication can replace PMM-derived credentials. HA startup logs now describe routing and credential requirements. Environment validation classifies authentication and redacts secrets more broadly. Tests cover routing, credential precedence, URL validation, startup warnings, and log masking.

Sequence Diagram(s)

sequenceDiagram
  participant StateUpdater
  participant vmAgentConfig
  participant RemoteWriteBuilder
  participant buildVMAgentProcess
  participant vmagent
  StateUpdater->>vmAgentConfig: deployment context and parsed VM URL
  vmAgentConfig->>RemoteWriteBuilder: select HA or standalone routing
  RemoteWriteBuilder-->>vmAgentConfig: endpoint and credential source
  vmAgentConfig->>buildVMAgentProcess: scrape configuration and remote-write settings
  buildVMAgentProcess-->>vmagent: arguments and environment variables
Loading

Priority: ➖ Normal

Merge Risk: 🟡 Moderate · up to 9fb2b

Credentialed HTTP targets may expose remote-write credentials, and malformed override URLs can leave vmagent running without delivering metrics. Constrain the former and validate concrete overrides before merging.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main change: reworking vmagent remote-write routing.
Description check ✅ Passed The description includes the ticket number, feature build, problem, change details, dependencies, documentation status, and verification results. It is complete and aligned with the required template.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 3b543a67-fd54-4ecc-ac00-42860a6ab58a

📥 Commits

Reviewing files that changed from the base of the PR and between c808150 and 3482e18.

📒 Files selected for processing (20)
  • documentation/docs/install-pmm/install-HA-clustered.md
  • documentation/docs/install-pmm/install-pmm-server/deployment-options/docker/env_var.md
  • documentation/docs/reference/third-party/victoria.md
  • managed/cmd/pmm-managed/main.go
  • managed/models/victoriametrics_params.go
  • managed/models/victoriametrics_params_test.go
  • managed/services/agents/deps.go
  • managed/services/agents/state.go
  • managed/services/agents/state_test.go
  • managed/services/agents/vmagent.go
  • managed/services/agents/vmagent_golden_test.go
  • managed/services/agents/vmagent_ha.go
  • managed/services/agents/vmagent_ha_test.go
  • managed/services/agents/vmagent_standalone.go
  • managed/services/agents/vmagent_standalone_test.go
  • managed/services/agents/vmagent_test.go
  • managed/utils/envvars/parser.go
  • managed/utils/envvars/parser_test.go
  • utils/logger/protobuf.go
  • utils/logger/protobuf_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • percona/pmm-qa (manual)
  • percona/pmm (manual)
💤 Files with no reviewable changes (1)
  • managed/services/agents/deps.go

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Comment thread documentation/docs/reference/third-party/victoria.md Outdated
Comment thread documentation/docs/reference/third-party/victoria.md Outdated
Comment thread managed/services/agents/vmagent_ha.go
Comment thread managed/services/agents/vmagent_ha.go Outdated
Comment thread managed/services/agents/vmagent.go Outdated
Comment thread managed/utils/envvars/parser.go Outdated
Comment thread utils/logger/protobuf.go Outdated
4nte added 2 commits September 4, 2026 17:09
The standalone and HA split exists to keep the two deployment modes
maintainable, not to describe the configuration to operators. The
debug line keeps the remote-write URL and the credential source.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
Address the CodeRabbit review on the vmagent remote-write paths.

The HA startup warning accepted half a basic-auth pair as a credential
and treated a bearer token or custom headers as none. Environment
validation and HARemoteWriteWarning now share one predicate,
envvars.VMAgentRemoteWriteAuthFromEnv, which counts both basic-auth
variables or any other vmagent authentication method as complete. Half
a pair is warned about in every mode, not only next to an injected
VMAGENT_remoteWrite_url, because it breaks authentication everywhere.

MaskDSN evaluated its "@" heuristic before the KEY=value secret check,
so a password containing "@" leaked everything after it into the
SetStateRequest debug dump. The secret check now runs first.

The ParseEnvVars trace line printed URL userinfo for PMM_VM_URL and
VMAGENT_remoteWrite_url; redactSecretEnvVar now drops it.

Docs: credentials in PMM_VM_URL travel in clear text over http, and the
VMAGENT_remoteWrite_url override also redirects PMM Server's own
vmagent when an external VictoriaMetrics is configured.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
@4nte
4nte marked this pull request as ready for review September 4, 2026 15:53
@4nte
4nte requested review from a team as code owners September 4, 2026 15:53
@4nte
4nte requested review from JiriCtvrtka and ademidoff and removed request for a team September 4, 2026 15:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 4d2db86f-a134-42ea-b88a-38e8668367a8

📥 Commits

Reviewing files that changed from the base of the PR and between 3482e18 and 9cfe0b1.

📒 Files selected for processing (9)
  • documentation/docs/reference/third-party/victoria.md
  • managed/services/agents/vmagent.go
  • managed/services/agents/vmagent_ha.go
  • managed/services/agents/vmagent_ha_test.go
  • managed/services/agents/vmagent_test.go
  • managed/utils/envvars/parser.go
  • managed/utils/envvars/parser_test.go
  • utils/logger/protobuf.go
  • utils/logger/protobuf_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • percona/pmm-qa (manual)
  • percona/pmm (manual)
🚧 Files skipped from review as they are similar to previous changes (2)
  • documentation/docs/reference/third-party/victoria.md
  • managed/services/agents/vmagent_test.go

Included review availability: Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Comment thread managed/services/agents/vmagent_ha.go Outdated
Comment thread utils/logger/protobuf.go
4nte added 4 commits September 4, 2026 18:37
When VMAGENT_remoteWrite_url is injected every vmagent writes there and
PMM_VM_URL takes no part in writes, yet HARemoteWriteWarning still
inspected it and told the operator to add credentials to a URL nobody
writes to. Environment validation already reports the injected
endpoint's credential situation, so the HA warning now stays silent
whenever the write URL is injected.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
envSecretRe used "." and "$" without the s flag, so a KEY=value entry
whose value spans lines never matched and fell through to the DSN
heuristic, which returns anything without "@" unmasked and leaks the
tail after "@" otherwise. pmm-agent passes every process env entry
through RedactString, so a multiline password would have reached its
log. The pattern now spans newlines; a regression test covers it.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
AGENTS.md forbids %q in error and log messages. Replace the five uses
this branch introduced: the VictoriaMetrics URL validation error, the
PMM_VM_URL environment error, and three test assertion messages.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
@4nte

4nte commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Referring to @coderabbitai finding / concern, PMM_VM_URL accepts http://username:password@host, and when it does, the VictoriaMetrics Basic Auth credentials travel in clear text. This PR does not close that
off, and I am accepting it rather than resolving it.

Why we are not enforcing https here:

  • It is not a regression. On main, PMM_VM_URL was validated by a bare url.Parse with no
    scheme or host check at all. This PR tightens that: ParseVictoriaMetricsURL
    (managed/models/victoriametrics_params.go) now requires http/https plus a host, rejects
    opaque URLs, and redacts the URL in its error text.
  • Plain HTTP is a legitimate, supported topology. In HA, PMM_VM_URL points at vmauth as an
    in-cluster service, and PMM Server's own agent reaches its own pod's nginx over loopback.
    Rejecting credentialed http would break those deployments while adding no protection on a
    trusted cluster network. PMM cannot distinguish a trusted hop from an untrusted one; the
    transport is the operator's call.

What the PR does do to limit exposure:

  • Credentials are stripped out of the URL and reach vmagent through its environment only. They
    never appear on the vmagent command line or inside the write URL (parseURLCredentials and
    buildVMAgentProcess in managed/services/agents/vmagent.go).
  • No error path echoes the URL: parse failures unwrap *url.Error, and validation errors use
    URL.Redacted().
  • VMAGENT_* variables are excluded from the startup environment log
    (managed/utils/envvars/parser.go).
  • An injected VMAGENT_remoteWrite_url suppresses PMM-derived credentials, so a PMM credential
    is never sent to an endpoint PMM did not choose.
  • The behaviour is documented for operators in
    documentation/docs/reference/third-party/victoria.md: "Credentials in PMM_VM_URL travel in
    clear text over http. Use https whenever metrics leaves a trusted network."

Redact KEY=value environment entries whose key contains characters
outside the shell alphabet, such as my-token or npm's
npm_config_//registry.npmjs.org/:_authToken. The Nomad agent inherits
pmm-agent's whole environment and pmm-agent logs it at debug level, so
such host variables can reach MaskDSN.

The key may not contain "@" or whitespace, otherwise a DSN whose user or
database name contains a marker word ("tokens", "secrets") would be read
as a key and its password echoed. Two rows guard that.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
Comment thread managed/services/agents/vmagent_golden_test.go
Comment thread managed/utils/envvars/parser.go Outdated
Comment thread managed/models/victoriametrics_params.go
Comment thread managed/utils/envvars/parser.go Outdated
Comment thread managed/services/agents/vmagent.go
An empty VMAGENT_* variable is dropped with a startup warning instead
of being forwarded or rejected. vmagent cannot use an empty value: an
empty remote-write URL or logger level stops it, and an empty
basic-auth pair silently disables authentication while it counted as
a complete credential and displaced PMM's own. Empty values are a
routine Helm and compose artifact, so they no longer keep
pmm-managed-init from starting.

redactSecretEnvVar parses a scheme-less user:pass@host as an
authority, so its credentials no longer reach the trace log.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
Comment thread managed/utils/envvars/parser.go
Comment thread managed/utils/envvars/parser.go Outdated
@ademidoff

Copy link
Copy Markdown
Member

Re-reviewed at be21a4b54. All 13 of my comments are addressed — I re-checked each against the current head and ran the two I could: the @-in-path redaction rows pass through intact, and the golden test now passes with PMM_PROMSCRAPE_MAX_SCRAPE_SIZE and PMM_INTERFACE_TO_BIND set. The two declines are fine by me; the benchmark numbers and the vmagent 3.9.1 output answer what I was actually asking.

Nothing outstanding from my side. The only things I'd still call blocking are Jiri's two most recent comments, both of which I reproduced:

  • Empty PMM_VM_URL (managed/utils/envvars/parser.go:225) — ParseEnvVars(["PMM_VM_URL="]) returns invalid VictoriaMetrics URL '/', so init exits 1 on a value that boots today.
  • Additive auth masking a half pair (managed/utils/envvars/parser.go:442) — with VMAGENT_remoteWrite_headers plus only basicAuth_username: classification is Complete, no half-pair warning, HARemoteWriteWarning silent, and credentialReplaced still drops PMM's pair, so the emitted env is a lone username. Worth flagging that this interacts with the fix to my partial-pair comment — withholding PMM's half is the right call, it's the warning that should catch it that gets bypassed.

One more from inside Jiri's second comment that has no thread of its own, so it may get lost: a comma-separated VMAGENT_remoteWrite_url only gets its first element redacted, in both the vmagent Debug line (managed/services/agents/vmagent.go:234) and redactSecretEnvVar. Debug/Trace-gated so not release-blocking on its own, but the PR supports comma-separated lists by design.

A value that is set but empty was accepted before PMM_VM_URL gained its
own validation, and kingpin falls back to the flag default for it, so
rejecting it stopped pmm-managed-init on a configuration that had always
started. Ignore it with a warning naming the variable, the way an empty
VMAGENT_* variable is already handled.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
An additive method shared a case with the complete-pair check, so it
returned Complete before the half-a-pair branch could return Partial.
Setting a tenant header or a client certificate alongside a lone
basicAuth username therefore silenced both the half-pair warning and the
HA warning, while the credential was still withheld and vmagent was
handed a username with no password. Additive methods now fall through
the Partial check; exclusive ones stay above it.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
Two copies of the same redaction had drifted apart and both leaked.
Parsing a comma-separated remote-write URL as a single URL leaves
everything after the first comma in the path, so only the first
element's userinfo was dropped, in the trace of the environment and in
the vmagent debug line. ParseVictoriaMetricsURL redacted by clearing
URL.User, which a scheme-less value never populates because url.Parse
leaves it in Opaque, so a credentialed PMM_VM_URL without a scheme was
named in full in an error logged at Error level.

Replace both with one helper that splits the value on commas and
redacts each element, parsing a scheme-less one as an authority.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
Comment thread managed/models/victoriametrics_params.go
Comment thread managed/utils/envvars/parser.go Outdated
A comma separates the URLs of a remote-write list and is also legal inside
userinfo, so splitting on it first hands the front of a password to an element
of its own, where it no longer looks like a credential and was printed as it
stood. A password with three commas kept three of its four segments, in a
startup error, in the environment dump and in the vmagent debug line.

Split only a value whose every element carries a scheme, which is what vmagent
requires of a remote-write URL. Anything else is redacted as the single URL it
is, so a comma in a password no longer splits anything, and a value that cannot
be parsed, or that still shows an '@' after a comma, is redacted whole.

Parsing alone would not have been enough: in user:1234,5678@host the first
fragment parses as a host and a port and raises no error at all.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
Any remote-write header counted as a complete credential, so an operator who
set a tenant identifier lost the warning that nothing authenticates the writes,
and lost the one about half a credential in PMM_VM_URL with it. The writes then
failed with nothing to explain them.

Classify the header by what it carries: an Authorization or Proxy-Authorization
header with a value authenticates the request, anything else does not. A client
certificate keeps counting, since it authenticates whatever it is sent with.

Whether PMM withholds its own credential is a separate question and is
unchanged: a header composes with a basic-auth pair rather than replacing one.

Signed-off-by: Ante Gulin <ante.gulin@percona.com>
@4nte
4nte requested a review from JiriCtvrtka September 21, 2026 14:52
@ademidoff
ademidoff temporarily deployed to PMM-14678-vmagent-write-paths - pmm-doc-3 PR #5887 September 28, 2026 08:16 — with Render Destroyed
Signed-off-by: Ante Gulin <ante.gulin@percona.com>
@4nte
4nte merged commit 3bb9d2a into main Sep 28, 2026
30 checks passed
@4nte
4nte deleted the PMM-14678-vmagent-write-paths branch September 28, 2026 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Documentation changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants