Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Harness): support user secrets #1176

Merged
merged 17 commits into from
Apr 12, 2024

Conversation

IronCore864
Copy link
Contributor

@IronCore864 IronCore864 commented Apr 3, 2024

Add support for user secrets in Harness. Changes:

  • Add a new API Harness.add_user_secret which simulates juju add-secret.
  • add_model_secret is deprecated, use add_charm_secret. For now, add_model_secret is an alias to add_charm_secret.

Use case example:

config.yaml:

options:
  mysec:
    type: secret
    description: "tell me your secrets"

charm.py:

class MyVMCharm(ops.CharmBase):
    def __init__(self, framework: ops.Framework):
        super().__init__(framework)
        framework.observe(self.on.config_changed, self._on_config_changed)
    def _on_config_changed(self, event: ops.StartEvent):
        mysec = self.config.get('mysec')
        if mysec:
            sec = self.model.get_secret(id=mysec, label="mysec")
            self.config_from_secret = sec.get_content()

test_charm.py:

def test_config_changed(harness):
    secret_content = {'password': 'foo'}
    secret_id = harness.add_user_secret(secret_content)
    # grant the user secret to the app
    harness.grant_secret(secret_id, 'webapp')
    harness.begin()
    harness.update_config({'mysec': secret_id})
    secret = harness.model.get_secret(id=secret_id).get_content()
    assert harness.charm.config_from_secret == secret.get_content()

@IronCore864 IronCore864 changed the title feat: support user secret feat(Harness): support user secret Apr 3, 2024
ops/testing.py Outdated Show resolved Hide resolved
@IronCore864 IronCore864 marked this pull request as ready for review April 6, 2024 05:14
Copy link
Contributor

@tonyandrewmeyer tonyandrewmeyer left a comment

Choose a reason for hiding this comment

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

Looking good - a few little nits and a couple of queries.

Other questions/comments:

  • The trigger_secret_expiration method should probably raise an error if it's used with a user secret. Is that already the case via permissions checking?
  • Likewise for trigger_secret_rotation.
  • It doesn't seem like we are testing the permission code changes. I think we'd want to have tests that verify that those work as expected.

ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
test/test_testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
Copy link
Collaborator

@benhoyt benhoyt left a comment

Choose a reason for hiding this comment

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

I agree with Tony's comments. I'll review further later. For now, can you please add a PR description with a brief description of the new API and with a usage example?

@IronCore864
Copy link
Contributor Author

Looking good - a few little nits and a couple of queries.

Other questions/comments:

  • The trigger_secret_expiration method should probably raise an error if it's used with a user secret. Is that already the case via permissions checking?
  • Likewise for trigger_secret_rotation.
  • It doesn't seem like we are testing the permission code changes. I think we'd want to have tests that verify that those work as expected.

Changed trigger_secret_expiration and trigger_secret_rotation to raise an error on user secret, also added two unit tests.

For user secret permissions, there are some unit tests.

@benhoyt benhoyt changed the title feat(Harness): support user secret feat(Harness): support user secrets Apr 9, 2024
Copy link
Collaborator

@benhoyt benhoyt left a comment

Choose a reason for hiding this comment

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

This looks good to me -- thanks. Just a few minor comments.

ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
Copy link
Contributor

@tonyandrewmeyer tonyandrewmeyer left a comment

Choose a reason for hiding this comment

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

Can we adjust _ensure_secret_owner so that it explicitly talks about user secrets? It could have a user_secret = secret.owner_name == self.model.uuid and an and not user_secret, although that isn't strictly necessary, so maybe just a comment explaining the user secret situation, with the comment that explains unit and app permissions?

I would also feel more comfortable if we had tests that explicitly made sure that user secrets fail ownership checks. This will prevent regressions in the future if we change how the permissions checks are done.

ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
ops/testing.py Outdated Show resolved Hide resolved
@IronCore864
Copy link
Contributor Author

Can we adjust _ensure_secret_owner so that it explicitly talks about user secrets? It could have a user_secret = secret.owner_name == self.model.uuid and an and not user_secret, although that isn't strictly necessary, so maybe just a comment explaining the user secret situation, with the comment that explains unit and app permissions?

I would also feel more comfortable if we had tests that explicitly made sure that user secrets fail ownership checks. This will prevent regressions in the future if we change how the permissions checks are done.

Yes it makes sense. I have added a test to try to do Secret.get_info to validate the ownership.

@IronCore864
Copy link
Contributor Author

IronCore864 commented Apr 12, 2024

Status update: John has started a discussion in the juju development channel, now the preferred names are "application secrets" and "charm secrets", it seems it's not decided yet, I'll wait for a final conclusion before merging this one.

Copy link
Contributor

@tonyandrewmeyer tonyandrewmeyer left a comment

Choose a reason for hiding this comment

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

LGTM!

@IronCore864 IronCore864 merged commit 8ef5ccf into canonical:main Apr 12, 2024
28 checks passed
@IronCore864 IronCore864 deleted the user-secrets-support branch April 12, 2024 04:57
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