Add proxy auth support and status/metrics commands - #81
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a84f72c1e1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Updated based on Codex review feedback:
|
val-ms
left a comment
There was a problem hiding this comment.
Thanks for the contribution. The proxy auth and monitoring additions are useful directions, but I think this needs changes before we can merge.
Blocking issues:
-
cvd config setis currently broken for normal use. The new optional--proxy-certand--proxy-cert-keyoptions useclick.Path(exists=True)withdefault="", so Click validates the empty default and exits before the command runs. I reproduced this locally withcvd config set --dbdir /tmp/db, which fails withInvalid value for '--proxy-cert': Path '' does not exist.These should default toNoneor otherwise avoid validating an absent optional path, and the CLI behavior should be covered by tests. -
The PR says it closes #30, but the update path still requires DNS before any HTTP/proxy download can happen.
db_update()still calls_query_dns_txt_entry()and returns1whendns_version_tokensis empty, so environments without direct DNS still cannot update through an HTTP proxy. Please either remove theCloses #30claim or implement and test a real no-DNS fallback. -
Proxy credentials can leak in logs/config output when credentials are embedded in
proxy_url._get_proxy_configuration()logs the full proxy URL in the unauthenticated branch, sohttp://user:pass@proxy.example.com:8080exposes the secret.config_show()only masksproxy_pass, not credentials already present inproxy_url. Please sanitize userinfo in all displayed/logged proxy URLs.
Other requested changes:
-
The PR body still claims Basic, Digest, NTLM, and certificate-based auth. The current implementation embeds credentials in the proxy URL, which Requests turns into Basic
Proxy-Authorization; it does not implement Digest or NTLM. Please narrow the claim or add real support/tests for those auth types. -
cvdupdate_last_check_timestampis documented as a Unix timestamp but emits milliseconds (time.time() * 1000). Please either emit seconds or rename/re-document it as milliseconds. -
Prometheus label values are interpolated without escaping. Custom database names containing quotes, backslashes, or newlines will produce invalid exposition output. Please escape label values per Prometheus text format rules.
-
CHANGES.mdstill contains placeholder PR links (pull/XX) and says this closes #30. Please update those before merge.
Compatibility note:
This PR also conflicts with PR #88. I checked the current heads with git merge-tree; #81 merges cleanly with #87, but conflicts with #88 in cvdupdate/__main__.py and cvdupdate/cvdupdate.py. The conflict is semantic as well as textual: both PRs introduce or redefine status, both change config set, and #88 restructures config/state handling that #81 builds on. If #88 moves forward, this PR will need to be rebased and reconciled around the CLI design, especially the meaning of status.
Local verification: the PR test suite passes for me (37 passed in 3.05s), and the CLI/config regressions above were reproduced in an isolated temporary venv.
00e2b51 to
ba87894
Compare
|
Thanks for the detailed review @val-ms. I have addressed each point. Blocking issues:
Other requested changes:
While addressing the above I fixed a few related issues:
On the #88 overlap: agreed. If #88 lands first I will rebase and reconcile the status command and config set design. Happy to coordinate on ordering. Test suite passes locally, 51 passed. |
Rebased onto current main (post-Cisco-Talos#88 snake_case config + `status`). The health/currency command is named `cvd health` to avoid colliding with Cisco-Talos#88's `cvd status`, which is left untouched. Proxy: proxy_url/user/pass from CVDUPDATE_PROXY_* env vars or `config set --proxy-*`. Credentials are URL-encoded and embedded in the proxy URL so requests sends Proxy-Authorization. Only Basic-via-URL is supported. Credentials are redacted from logs and from `config show` (both text and --json); the config file is written 0600 and plaintext-at-rest is documented, with env vars recommended for secrets. Malformed, IPv6, and scheme-less proxy URLs are handled without crashing `config show`/`update`. health: per-database local-vs-DNS version, file age, and cooldown state; --json for machine output; --check exits 0/1/2. A transient DNS failure does not fail --check when the on-disk databases are current. db_status tolerates malformed state entries instead of crashing. metrics: Prometheus exposition to stdout, or --serve (ThreadingHTTPServer with address reuse, a per-request timeout, and a 500 on collection error). Label values are escaped; the last-check timestamp is Unix seconds taken from the status-collection time. health and metrics keep stdout free of log lines so --json and the exposition output stay machine-parseable. Closes Cisco-Talos#7, Cisco-Talos#9.
|
Rebased onto current Your May 29 points are addressed: While rebasing I also tightened a few things the feature needs to actually hold One behavior choice worth flagging: I kept this focused on the three features. Two adjacent things I noticed I've No rush given your triage load @val-ms - happy to adjust scope however makes this |
val-ms
left a comment
There was a problem hiding this comment.
I found four actionable issues that should be addressed before merge:
-
config showcan still leak embedded proxy credentials for scheme-less proxy URLs._get_proxy_configuration()prefixeshttp://before logging, butconfig showsanitizes the raw stored string. For a stored value such asalice:secret@proxy.example.com:8080,urlparse()treatsaliceas the scheme, sees no username/password, and_sanitize_proxy_url()returns the secret unchanged. Please normalize scheme-less URLs before sanitizing, or make_sanitize_proxy_url()handle this form directly, and add a regression test for scheme-less embedded userinfo. -
_save_config()writes the config before applyingchmod 0600. A new config file containingproxy_passcan be created under the process umask, often world-readable, before permissions are tightened. Existing config files may also remain too permissive through the write. Please create/truncate the config with owner-only permissions up front, or chmod an existing config before writing the plaintext password. -
The new tests use
CliRunner(mix_stderr=False), butsetup.pyallowsclick>=7.0, and current Click 8.4.2 has removed that constructor argument. The focused suite fails under a valid dependency set. Click 8.4 still exposesresult.stdoutandresult.stderr, so the tests can likely be updated to use those properties instead of the removed constructor option, unless the project intentionally pins an older Click. -
git diff --check origin/main...HEADfails due extra blank lines at EOF incvdupdate/metrics.py,tests/test_metrics.py,tests/test_proxy_auth.py, andtests/test_status.py.
Local test notes: with a temp venv under /private/tmp, tests/test_proxy_auth.py tests/test_status.py tests/test_metrics.py passed (49 passed). The CLI subset failed only for the mix_stderr=False tests after excluding localhost-bind tests; the two localhost server tests passed when rerun outside the sandbox.
…mpat - config show: mask credentials in scheme-less proxy URLs (urlparse read the username as the scheme) - _save_config: create and truncate config as 0600 and chmod before writing, so a plaintext proxy_pass is never briefly world-readable - tests: tolerate Click 8.2 and later where CliRunner(mix_stderr=False) is gone - strip trailing blank lines flagged by git diff --check
|
Thanks for the review, @val-ms. All four points are addressed:
One related thing I found while on point 3: config set --proxy-pass (the prompt form) relies on Click 8's optional-value flags, so it errors on Click 7 with "option requires an argument". The declared floor in setup.py is click>=7.0. Happy to bump it to click>=8.0 here, or send it as a small separate change, whichever you prefer. I could also add a python_requires at the same time. The Prometheus polish I mentioned earlier (grouping each metric family and a couple of naming conventions), I'm happy to still send as the separate follow-up. |
Closes #7 and #9. All existing tests pass, plus new unit tests covering the proxy, status, and metrics paths, including Click-level CLI tests.