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

[DPE-2342] Charm Relation (i.e. 'external') Secrets #91

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

juditnovak
Copy link
Contributor

@juditnovak juditnovak commented Aug 26, 2023

Disclaimer

Here we introduce Relations Secrets on top of the existing data_interfaces logic.

New interfaces:

  • get_relation_secret_data() (Provides, Requires)
  • set_relation_secret_fields() (Provides)
  • get_relation_secret_fields(), get_relation_secret_fields() (Requires)

POC demo of usage demonstrated on Opensearch: canonical/opensearch-operator#116

@juditnovak juditnovak changed the base branch from main to DPE-2394_juju3_pipeline August 26, 2023 12:10
@juditnovak juditnovak force-pushed the DPE-2342_relation_secrets branch 8 times, most recently from 203c86e to 11a9374 Compare August 27, 2023 20:44
@juditnovak juditnovak changed the title [WIP][IGNORE][DPE-2342] relation secrets [DPE-2342] relation secrets Aug 27, 2023
@juditnovak juditnovak changed the title [DPE-2342] relation secrets [DPE-2342] Charm Relation (i.e. 'externa') Secrets Aug 27, 2023
@juditnovak juditnovak changed the title [DPE-2342] Charm Relation (i.e. 'externa') Secrets [DPE-2342] Charm Relation (i.e. 'external') Secrets Aug 27, 2023
Copy link
Member

@marceloneppel marceloneppel left a comment

Choose a reason for hiding this comment

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

Overall it looks great! I think we are in the right path with this implementation.

About the cache, from what I could see, it will be restricted to the event lifetime only.

I left comments about other details.

lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
tests/unit/test_data_interfaces.py Show resolved Hide resolved
lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
tests/integration/kafka-charm/src/charm.py Outdated Show resolved Hide resolved
@juditnovak juditnovak force-pushed the DPE-2342_relation_secrets branch 5 times, most recently from 63de4bd to e0c9efa Compare August 29, 2023 17:17
Copy link
Contributor

@shayancanonical shayancanonical left a comment

Choose a reason for hiding this comment

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

I really like the direction that this implementation is taking! Abstracting away whether a relation data is stored in a secrets backend or in the relational databag is an excellent idea!

A couple of high level comments/questions I had after my first review were:

  1. SecretCache is not really a cache - it is a wrapper around a Secret in a Juju secrets backend
  2. Should we allow the Requires application to decide which fields are SECRET_FIELDS instead of hardcoding them? (and fallback to the hardcoded value if they are not specified?) -> this will allow users to specify all the fields that they want as secrets

lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
@juditnovak
Copy link
Contributor Author

@shayancanonical

SecretCache: Your point is valid, it is

  1. An abstraction layer to handle direct interaction with the Juju Secret Strore
  2. However it IS a cache too :-)

The point is that, once you fetch a secret via a SecretCache object, it won't be fetched again within the same event scope.
So it's kinda providing a smart layer between DataInterfaces and Juju. It's both handling the interactions AND if the interaction is avoidable it would just return the previously cached data.

(I may need to polish up a code, there could be errors on this still :-) )

Base automatically changed from DPE-2394_juju3_pipeline to main August 29, 2023 21:24
Copy link
Contributor

@shayancanonical shayancanonical left a comment

Choose a reason for hiding this comment

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

Looks great! Just a flood of small nits/questions

lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
lib/charms/data_platform_libs/v0/data_interfaces.py Outdated Show resolved Hide resolved
Copy link
Contributor

@paulomach paulomach left a comment

Choose a reason for hiding this comment

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

I'm missing some of the secret context, but could follow the implementation. Overall looking good, my nits are well represented by other reviews

@juditnovak juditnovak force-pushed the DPE-2342_relation_secrets branch 4 times, most recently from ec4c19c to f2b8bc9 Compare September 1, 2023 00:15
DON'T USE the encapsulated helper variable outside of this function
"""
if not hasattr(self, "_cached_jujuversion"):
self._cached_jujuversion = None
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Alternatively, I can add this init() function:

def __init__(self, handle: Handle, relation: Relation, app: Optional[Application] = None, unit: Optional[Unit] = None):
    super().__init__(handle, relation, app, unit)
    self._cached_jujuversion = None
    self._cached_secrets = None

...and then copy this into 6 --currently very pretty, one-liner-- descendant classes:

def __init__(self, handle: Handle, relation: Relation, app: Optional[Application] = None, unit: Optional[Unit] = None):
    super().__init__(handle, relation, app, unit)

...but this is so ugly, that it doesn't even feel right -- just for two internal helper variables, that aren't supposed to be used outside of their encapsulated scope.... That I'd rather go with the technically less safe, but in another sense still more elegant solution. As instructions on the property functions clearly indicate: the helper variabes are meant to be encapsulated inside, noone should refer to them otherwise.

Anyway, if strong feelings on the other side, I can go for the __init__() solution.

Copy link
Contributor

Choose a reason for hiding this comment

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

less ugly?

Suggested change
self._cached_jujuversion = None
if not hasattr(self, "_cached_jujuversion") or not self._cached_jujuversion:
self._cached_jujuversion = JujuVersion.from_environ()

@juditnovak juditnovak marked this pull request as ready for review September 4, 2023 07:17
@@ -934,6 +981,11 @@ def tls(self) -> Optional[str]:
if not self.relation.app:
return None

if self.secrets_enabled:
secret = self._get_secret("tls")
Copy link
Contributor

Choose a reason for hiding this comment

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

nit (use walrus):

if secret := self._get_secret("tls"):
    return secret.get("tls")

@@ -331,6 +334,33 @@ def _on_topic_requested(self, event: TopicRequestedEvent):
deleted - key that were deleted"""


# Local map to associate labels with secrets potentially as a group
Copy link
Contributor Author

Choose a reason for hiding this comment

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

[CRITICAL] Increase LIBVERSION !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

@shayancanonical
Copy link
Contributor

@juditnovak is this PR still revelant? if not, should we close?

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.

4 participants