fix(core): watcher block dotted-path literals → real substitutions + sanitize coverage (#172) - #175
Draft
fupelaqu wants to merge 3 commits into
Draft
fix(core): watcher block dotted-path literals → real substitutions + sanitize coverage (#172)#175fupelaqu wants to merge 3 commits into
fupelaqu wants to merge 3 commits into
Conversation
… coverage (Closed Issue #172) The elastic.watcher block's credential keys were literal strings (method = elastic.credentials.method etc.), so the watcher never inherited the main credentials and auth auto-detection picked the garbage string "elastic.credentials.api-key" as ApiKeyAuth. - softnetwork-elastic.conf: all watcher keys now inherit the resolved elastic.credentials value via real substitutions (optional ${?elastic.credentials.method} — that key is absent by design after REPL.2); scheme/host/port inherit too (watcher targets the main cluster by default); ${?ELASTIC_WATCHER_*} overrides preserved. - CliConfig.envLayer: ELASTIC_WATCHER_* family gets the same empty-env-is-unset treatment as the main family (coordinates trimmed, credential values verbatim). - CliConfig.sanitize: empty/missing watcher scheme/host/port repair to the (already repaired) main connection coordinates. - CliConfigSpec: 6 new pure-JVM tests (inheritance incl. custom values through the builtin substitutions, env override, empty-env-is-unset, sanitize repair, garbage-ApiKeyAuth regression). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #172. Refs #169 (0.20.2 line). STACKED ON #165 (
feature/REPL.2) — merge after it; GitHub will retarget tomainwhen #165 merges.Root cause
In
core/src/main/resources/softnetwork-elastic.conf, theelastic.watcherblock's five credential-ish keys were literal strings, not HOCON substitutions:Consequences:
watcher.api-keyresolved to the non-empty garbage string"elastic.credentials.api-key", whichElasticAuthMethod.fromCredentialsauto-detected as ApiKeyAuth (apiKey.exists(_.nonEmpty));elastic.watcher.*paths sat entirely outside the sanitize / empty-env-≡-unset treatment REPL.2 (REPL.2 — Connection config precedence: CLI flag > env var > config file > default #165) added forelastic.credentials.*.Fix
softnetwork-elastic.conf— every watcher key now inherits the resolvedelastic.credentialsvalue via a real substitution, with the${?ELASTIC_WATCHER_*}per-key env overrides preserved:method = ${?elastic.credentials.method}— optional substitution: after REPL.2 that key is absent unlessELASTIC_AUTH_METHODis set (auth auto-detect design); a required substitution would fail resolution.username/password/api-key/bearer-token=${elastic.credentials.<key>}— required substitutions, safe because the post-REPL.2 credentials block still carries""defaults for all four (verified in the worktree conf), so the keys are always present.Decision — scheme/host/port inherit too (
${elastic.credentials.scheme|host|port}instead of their ownhttp/localhost/9200literals). Rationale: the watcher targets the same cluster as the main connection (principle of least surprise); grep-verified that nothing in the repo constructs a client fromElasticConfig.watchertoday, so this is behavior-safe — and with nothing set the resolved values are byte-identical to the old literals.ELASTIC_WATCHER_SCHEME/HOST/PORTstill override per key for a genuinely separate watcher cluster. Known (pre-existing) limitation: substitutions resolve inside the builtin layer, so watcher inheritance follows defaults andELASTIC_*env vars, not CLI flags / user-file credential overrides — documented, unchanged from the credentials semantics REPL.2 shipped.CliConfig— REPL.2's mechanisms extended to the watcher paths:envLayernow covers theELASTIC_WATCHER_*family with the exact same rules: empty/whitespace-only env ≡ unset; scheme/host/port values trimmed; credential values verbatim.ELASTIC_WATCHER_AUTH_METHODdeliberately stays out of this layer — parity withELASTIC_AUTH_METHOD, which only enters through the builtin tail.sanitize(refactored into arepairEmptyhelper, generalized per path list): an empty/missing watcherscheme/host/portnow repairs to the already-repaired main connection coordinate (inherit semantics) instead of being left broken.Test evidence
sbt "core/testOnly *CliConfigSpec"— 18/18 green (12 pre-existing REPL.2 matrix tests untouched + 6 new):watcher.methodabsent; no key carries the old dotted-path garbage;ELASTIC_CREDENTIALS_*at load time);ELASTIC_WATCHER_*env overrides beat inherited and file values (trim/verbatim rules asserted);ELASTIC_WATCHER_HOST/_PORTbehave as unset (file value wins; inherited default survives);ElasticConfig(...).watcher.authMethod == Nonewith nothing set (was ApiKeyAuth from the garbage string).Also green:
sbt "+ core/compile"(2.12.20 + 2.13.16),sbt scalafmtAll,sbt headerCheck. Pure JVM, no Docker; env and config-file layers injected through REPL.2's two-parameterbuildElasticConfigseam (noconfig.filesysprop mutation).Note:
install.shneeds no change — REPL.2's launcher empty-env unset loop already covers theELASTIC_WATCHER_*family.🤖 Generated with Claude Code