Skip to content

fix: add support for vault_secret_key - #421

Merged
abellotti merged 3 commits into
mainfrom
support_vault_key
May 14, 2026
Merged

fix: add support for vault_secret_key#421
abellotti merged 3 commits into
mainfrom
support_vault_key

Conversation

@abellotti

@abellotti abellotti commented May 13, 2026

Copy link
Copy Markdown
Contributor
  • When creating or updating credentials with HashiCorp vault secrets, require the vault_secret_key when users specify the vault_secret_path.

Summary by Sourcery

Require a vault key when using HashiCorp Vault-backed credentials and propagate it through the CLI and payloads, with corresponding documentation and tests.

New Features:

  • Add a --vault-secret-key option for credential add/edit commands to specify the key within a HashiCorp Vault secret.

Bug Fixes:

  • Prevent misconfiguration by enforcing that --vault-secret-key is required whenever --vault-secret-path is provided and validating this in CLI argument parsing.

Documentation:

  • Document the new --vault-secret-key option and its requirement alongside --vault-secret-path in the CLI man pages and usage examples.

Tests:

  • Extend credential add/edit tests to cover providing vault_secret_key in successful flows and to assert failures when vault_secret_path is supplied without vault_secret_key.

- When creating or updating credentials with HashiCorp vault
  secrets, require the vault_key when users specify
  the vault_secret_path.
@abellotti
abellotti requested a review from a team as a code owner May 13, 2026 18:01
@sourcery-ai

sourcery-ai Bot commented May 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

This PR adds explicit support for a required HashiCorp Vault key when using vault-based credentials, wiring a new --vault-key CLI option through argument parsing, validation, payload construction, tests, and documentation for both cred add and cred edit flows.

Sequence diagram for cred add/edit with required vault_key

sequenceDiagram
    actor User
    participant qpc_cred_add as qpc_cred_add
    participant qpc_cred_edit as qpc_cred_edit
    participant validate_vault_args as validate_vault_args
    participant build_credential_payload as build_credential_payload

    User->>qpc_cred_add: qpc cred add --vault-secret-path path --vault-key key
    qpc_cred_add->>validate_vault_args: validate_vault_args(args, cred_type)
    validate_vault_args-->>qpc_cred_add: args validated
    qpc_cred_add->>build_credential_payload: build_credential_payload(args, cred_type, add_none)
    build_credential_payload-->>qpc_cred_add: payload with vault_secret_path and vault_key

    User->>qpc_cred_edit: qpc cred edit --vault-secret-path path --vault-key key
    qpc_cred_edit->>validate_vault_args: validate_vault_args(args, cred_type)
    validate_vault_args-->>qpc_cred_edit: args validated
    qpc_cred_edit->>build_credential_payload: build_credential_payload(args, cred_type, add_none)
    build_credential_payload-->>qpc_cred_edit: payload with vault_secret_path and vault_key

    alt [vault_secret_path set and vault_key missing]
        qpc_cred_add->>validate_vault_args: validate_vault_args(args, cred_type)
        validate_vault_args->>validate_vault_args: logger.error(CRED_VAULT_KEY_REQUIRED)
        validate_vault_args->>validate_vault_args: sys.exit(1)
    end
Loading

File-Level Changes

Change Details Files
Add --vault-key option to cred add/edit and validate it when using HashiCorp Vault secrets.
  • Extend cred add/edit argument parsers with an optional vault_key argument and help text.
  • Update _validate_args in cred edit so vault_key participates in the "something changed" check.
  • In validate_vault_args, require vault_key whenever vault_secret_path is provided and keep mount-point dependency rules.
  • Propagate vault_key into the request payload in build_credential_payload when present.
qpc/cred/add.py
qpc/cred/edit.py
qpc/cred/utils.py
qpc/messages.py
Update tests to cover vault_key usage and error handling when missing.
  • Adjust existing green-path tests for vault-backed openshift and ansible credentials to pass --vault-key and assert it is present in the outgoing payload.
  • Add new tests ensuring cred add/edit fail with SystemExit and log CRED_VAULT_KEY_REQUIRED when vault_secret_path is given without vault_key.
qpc/tests/cred/test_vault_cred_add.py
qpc/tests/cred/test_vault_cred_edit.py
Document the new --vault-key requirement and option in the CLI man pages and examples.
  • Update man page command synopsis for cred add/edit to include --vault-key alongside --vault-secret-path.
  • Document that --vault-secret-path requires --vault-key and describe the new --vault-key option semantics.
  • Refresh example commands to show usage of --vault-key with Vault-based credentials and bump the man page date.
docs/_build/qpc.1
docs/_build/QPC_VAR_PROGRAM_NAME.1
docs/_build/man-qpc.rst
docs/source/man-template.rst

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@codecov

codecov Bot commented May 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.49%. Comparing base (b5f5192) to head (1b4890f).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #421      +/-   ##
==========================================
+ Coverage   96.47%   96.49%   +0.01%     
==========================================
  Files         138      138              
  Lines        8690     8737      +47     
==========================================
+ Hits         8384     8431      +47     
  Misses        306      306              

☔ View full report in Codecov by Sentry.
📢 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.

@sourcery-ai sourcery-ai 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.

Hey - I've found 2 issues, and left some high level feedback:

  • In validate_vault_args, you enforce that vault_key is required when vault_secret_path is set, but there is no reciprocal check; consider adding a guard that errors if --vault-key is provided without --vault-secret-path (similar to the existing vault_mount_point validation) to prevent inconsistent CLI usage.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `validate_vault_args`, you enforce that `vault_key` is required when `vault_secret_path` is set, but there is no reciprocal check; consider adding a guard that errors if `--vault-key` is provided without `--vault-secret-path` (similar to the existing `vault_mount_point` validation) to prevent inconsistent CLI usage.

## Individual Comments

### Comment 1
<location path="qpc/cred/utils.py" line_range="175-178" />
<code_context>
     """
     # Get vault options (use getattr for legacy test compatibility)
     vault_secret_path = getattr(args, "vault_secret_path", None)
+    vault_key = getattr(args, "vault_key", None)
     vault_mount_point = getattr(args, "vault_mount_point", None)

</code_context>
<issue_to_address>
**issue (bug_risk):** Validate that --vault-key is not provided without --vault-secret-path

`validate_vault_args` currently requires `vault_key` when `vault_secret_path` is set, but not the reverse: `--vault-key` can be passed alone, leaving `vault_secret_path` falsy and bypassing validation. This permits an invalid config that contradicts the documented usage.

Please add a check such as:

```python
if vault_key and not vault_secret_path:
    logger.error(_(messages.CRED_VAULT_KEY_REQUIRES_PATH))
    sys.exit(1)
```

(or reuse an existing message) so `--vault-key` is rejected unless `--vault-secret-path` is also provided.
</issue_to_address>

### Comment 2
<location path="qpc/tests/cred/test_vault_cred_edit.py" line_range="144-153" />
<code_context>
+    def test_edit_vault_missing_key(
</code_context>
<issue_to_address>
**suggestion (testing):** Add an explicit test for `--vault-key` provided without `--vault-secret-path` to document and lock in the expected behavior.

You’ve covered the `--vault-secret-path` without `--vault-key` case. Please also add tests (for both `add` and `edit`) for the inverse: `--vault-key` provided without `--vault-secret-path`. That will lock in whether this should error or be ignored, and ensure the current behavior is validated via `sys.argv` and the resulting outcome (error or no-op).

Suggested implementation:

```python
        assert payload["vault_mount_point"] == "custom-mount"

    def test_edit_vault_missing_secret_path_with_key(
        self,
        capsys,
        requests_mock,
    ):
        """Test that vault key without vault secret path fails."""
        url = get_server_location() + CREDENTIAL_URI
        requests_mock.get(
            url,
            status_code=200,
            json={
                "name": "vault_cred",
                "type": "vault",
                "vault_secret_path": "secret/data/my-creds",
                "vault_key": "existing-key",
                "vault_mount_point": "secret",
            },
        )

        # Simulate CLI invocation with --vault-key but no --vault-secret-path
        sys.argv = [
            "qpc",
            "cred",
            "edit",
            "--name",
            "vault_cred",
            "--vault-key",
            "my-new-key",
        ]

        with pytest.raises(SystemExit) as exc:
            main()

        captured = capsys.readouterr()

        # Lock in current behavior: non-zero exit when vault-key is provided
        # without a matching vault-secret-path.
        assert exc.value.code != 0
        # Keep this assertion loose so it doesn't over-constrain messaging,
        # but still documents that the error mentions vault arguments.
        assert "vault" in captured.err.lower()

    def test_edit_vault_missing_key(
        self,
        capsys,
        requests_mock,
    ):
        """Test that vault secret path without vault key fails."""
        url = get_server_location() + CREDENTIAL_URI
        requests_mock.get(
            url,
            status_code=200,
            json={

```

1. The new test `test_edit_vault_missing_secret_path_with_key` assumes:
   - `sys` is imported (e.g., `import sys`) at the top of this file.
   - `pytest` is imported (e.g., `import pytest`) at the top of this file.
   - `main` is the CLI entrypoint already used in other tests in this module, and is imported accordingly.
   - The existing tests in this file already follow the `sys.argv` + `main()` pattern; if they use a different runner helper, adjust the invocation in this new test to match (e.g., `runner.invoke(...)` or a project-specific helper).
2. To fully address your original review comment (“for both `add` and `edit`”), a symmetric test should be added to `qpc/tests/cred/test_vault_cred_add.py`, e.g.:
   ```python
   def test_add_vault_missing_secret_path_with_key(capsys):
       """Test that vault key without vault secret path fails for add."""
       sys.argv = [
           "qpc",
           "cred",
           "add",
           "--name",
           "vault_cred",
           "--type",
           "vault",
           "--vault-key",
           "my-key",
       ]

       with pytest.raises(SystemExit) as exc:
           main()

       captured = capsys.readouterr()
       assert exc.value.code != 0
       assert "vault" in captured.err.lower()
   ```
   Place this new test alongside the existing `add`-side Vault tests and adjust the runner/imports to match the conventions in that file.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread qpc/cred/utils.py Outdated
Comment thread qpc/tests/cred/test_vault_cred_edit.py
- Make sure we catch the case where vault_key is specified
  without having secified the vault_secret_path.
- Preferring to use vault_secret_key instead of vault_key as to not
  confuse with keys uses to authenticate to the vault itself.
@abellotti abellotti changed the title fix: add support for vault_key fix: add support for vault_secret_key May 13, 2026

@infinitewarp infinitewarp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM! 👍

@abellotti
abellotti merged commit dd93d39 into main May 14, 2026
20 of 21 checks passed
@abellotti
abellotti deleted the support_vault_key branch May 14, 2026 14:47
@abellotti

Copy link
Copy Markdown
Contributor Author

Merging with the ci failure as this needs the API and camayoc PRs merged.
Successful standalone: https://jenkins-csb-smqe-stage.dno.corp.redhat.com/job/discovery-standalone/420/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants