-
Notifications
You must be signed in to change notification settings - Fork 8
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-3543] Zookeeper on Juju secrets (peer and for cross-charm relations #112
Conversation
7bcac6c
to
6be5d8c
Compare
6be5d8c
to
25837d8
Compare
25837d8
to
c71086f
Compare
PEER, | ||
self.state.cluster.relation.id, | ||
None, # type:ignore noqa -- Changes with the soon upcoming new version of DP-libs STILL within this POC | ||
): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NOTE: The # type: ignore
should not be needed anymore once canonical/data-platform-libs#137 is merged (may take a while 😅 )
Calling ain INTERNAL function is CLEARLY wrong, should be replaced with a public call once canonical/data-platform-libs#124 is finally addressed.
(It's a small thing I just never gt to it...)
self, | ||
relation: Relation | None, | ||
data_interface: DataRelation, | ||
component: Unit | Application, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotta check: do we really need component
still...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think so. In ZKServer
which inherits from that, we use component
in deciding hosts
.
peer_app_secrets=["sync-password", "super-password"], | ||
peer_unit_secrets=[ | ||
"ca-cert", | ||
"csr", | ||
"certificate", | ||
"truststore-password", | ||
"keystore-password", | ||
"private-key", | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: Could we move these to src/literals.py
?
Can be two lists, PEER_APP_SECRETS
and PEER_UNIT_SECRETS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe as class constants within ZKCluster
and ZKServer
respectively?
class ZKCluster:
SECRETS = ["sync-password", "super-password"]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I should have done that, my bad.
In fact that's even how I'm advertising this method in the spec 😅
Fixing.
if not event.secret.label: | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Under what conditions does this happen?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If your charm at any point just creates a secret w/o label. Or if a related charm may share (secret.grant()
) a secret with your charm.
Thus your charm is an observer of that secret that doesn't have a label -- and gets secret-changed
event notification once that secret changes.
We don't care about any of those potential secrets.
NOTE: label
is an OPTIONAL "sticker" we stick on secrets, so we have a way to identify them. As without, secret identification becomes... complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming that the labelling of secrets is something we handle in our lib then?
@@ -47,7 +47,7 @@ jobs: | |||
|
|||
integration-test: | |||
strategy: | |||
max-parallel: 1 | |||
# max-parallel: 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion/praise: Thank you for removing this! If the CI has been behaving, I'm 100% fine with removing max-parallel
entirely! Saves us a lot of hassle.
if not self.state.cluster.relation: | ||
return | ||
|
||
if event.secret.label == self.state.cluster.data_interface._generate_secret_label( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: What does this actually check? Ignorantly, to me it just seems like it's checking if a string == string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ask that, because generally we're trying to funnel every event in to cluster-relation-changed
. To me, there isn't a distinction between a 'secret-changed' and a 'relation-changed', conceptually I mean.
Am I fair in guessing that we can still observe secret-changed, and then call the relation-changed handler as normal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We check which secret changed.
Precisely since we don't actually care on a service level, if the unit
TLS secrets changed. While we DO care on a service level whether the sync-password
changed -- we need to cascade that down to the Zookeeper application.
So, while primarily you are right -- it's "just a relation-changed
thing", we still need to have extra, secrets-specific checks on this occasion.
I'm wondering that it may rather worth to group functionalities that may happen both on secret changes AND on databag changes into an update_service
function, which is called both in relation-changed
and in secret-changed
.
Does the response make sense...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, can we:
- Comment the
if not event.secret.label
to explain what it's for. - Comment the
if event.secret.label == self.state.cluster.data_interface._generate_secret_label()
line to explain why it's only app secrets we care about - Comment the docstring for the
_on_secret_changed
explaining why we handle this specifically (i.e the slow request time for secret content) - Replace the
if:
below to just callself._on_cluster_relation_changed(event)
class ClusterStateBase(Object): | ||
"""Collection of global cluster state for Framework/Object.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick: If this is just a Base, I think we can put it in src/core/models.py
) | ||
|
||
@property | ||
def peer_units_data_interfaces(self) -> Dict[Unit, DataPeerOtherUnit]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick/chore: Use dict[Unit, DataPeerOtherUnit]
. Dict
is deprecated.
@@ -80,6 +114,7 @@ def clients(self) -> Set[ZKClient]: | |||
clients.add( | |||
ZKClient( | |||
relation=relation, | |||
data_interface=self.charm.client_provider_interface, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
praise: Good god I'm pleased it was that smooth! Great work!
self, | ||
relation: Relation | None, | ||
data_interface: DataRelation, | ||
component: Unit | Application, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think so. In ZKServer
which inherits from that, we use component
in deciding hosts
.
return | ||
|
||
self.relation_data.update(items) | ||
delete_fields = [key for key in items if not items[key]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Maybe I'm being dim, but wouldn't this line ALWAYS return an empty list?
You're looping over a dict, which loops over keys. You're then keeping keys, that aren't keys in the dict, which they all are, because that's the loop value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the point:
In [4]: items = {'a': '', 'b': "something"}
In [5]: [key for key in items if not items[key]]
Out[5]: ['a']
Using update()
(but it's the same for set_secret()
in old-style charms) the way we delete is to update()
with ""
.
That's exactly what this list comprehension is distinguishing for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right got it.
May I suggest making that a tad more explicit?:
[for key:value in items.items() if value]
@@ -322,7 +363,7 @@ def certificate(self) -> str: | |||
@property | |||
def ca(self) -> str: | |||
"""The root CA contents for the unit to use for TLS.""" | |||
return self.relation_data.get("ca", "") | |||
return self.relation_data.get("ca-cert", "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
major We need to make sure this is backward compatible or we update the field during upgrade, otherwise after upgrade, this won't work properly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMPORTANT
HIGH PRIOROTY
(Note to myself)
major check note-to-myself Though pipelines confirm external relations functionality, I want to follow step-by-step that there's zero interference regarding cross-charm relations protocols (ZK event handlers vs. DP-libs event handlers) |
Early version of #129 |
Zookeeper on Juju Secrets both for Peer and Cross-charms Relations.
NOTE: This PR relies on small
data-platform-libs
updates that are still to be merged: canonical/data-platform-libs#138However I think the conten here is certainly ready for further discussions (while the above gets merged)