Secrets do not behave as expected
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Canonical Juju |
Fix Released
|
High
|
Ian Booth |
Bug Description
According to multiple conversations with Juju team, the expected behavior is:
https:/
https:/
Juju team explained the following behavior is expected for secrets:
1) Update a given secret value with "secret-set" (which creates revision N for this discussion)
2) secret-changed is thrown
3) In secret-changed: get the old value of the secret:
event.
4) Get the new value of the secret:
event.
5) Run any activities that need the secrets (e.g. changing a password in the database)
6) Commit back to Juju that revision N-1 is obsolete
event.
7) Finish the event: doFlush will be called from the juju agent side
I am currently running on Juju built from 3.3 commit: 230e203a72617a3
I can say this is not at all the behavior we've found.
First, in the secret-changed, I can run PDB and check the values of each of the calls above:
https:/
And we can see they are all the same. Therefore, the flow described above is not functional.
-------
Looking into Juju code, what I can see happening is the following:
In the agent managing the charm:
1) jujuc is called with "secret-set" to set a new value (new: revision N, old: revision N-1) [1]
2) UpdateSecret calls "update" [2]
3) update method registers a new update in secretChangeRec
Once the event is finished, the agent calls doFlush [4], which will iterate over each secret present in pendingUpdates and create a new secret with revision=N in the SecretBackend. Then, doFlush calls its API back to the controller with UpdateSecret request [5,6].
Then, UpdateSecrets is called in the controller, which then calls "updateSecrets"[7]. That method will eventually call: markObsoleteRev
-------
This issue can be confirmed as follows:
Set Juju to log all transactions to its own mongodb:
juju model-config -m controller logging-
While the event that issued a "secret-set" is finishing (i.e. running doFlush), then Juju controller will run several queries to its database. Filter the controller, logs, for example with:
$ kubectl logs -n controller-
It is possible to see that, at that moment, Juju controller will request an update in revision N-1 with "obsolete"=True.
-------
Based on:
https:/
Secret labels are not being used in this charm.
-------
REPRODUCER
$ git clone https:/
$ tox -e database-
# Attach the debug-hooks and run a password change action:
$ juju run postgresql-
-------
[1] https:/
[2] https:/
[3] https:/
[4] https:/
[5] https:/
[6] https:/
[7] https:/
[8] https:/
Changed in juju: | |
status: | New → Triaged |
Changed in juju: | |
status: | Fix Committed → Fix Released |
tags: | added: canonical-data-platform-eng |
To provide some more context:
* We are using app-scoped secrets
* Each secret represents the password that is used by the database and shared between the units
* There is just one model
The key part here is: /github. com/juju/ juju/blob/ 3e561add5940a51 0f785c83076b2bc c6994db103/ apiserver/ facades/ agent/secretsma nager/secrets. go#L704- L725
https:/
Removing it and I can see that, within secret-changed event, the "operator-password" respects the: get_content( ) # returns old value peek_content( ) # returns new value get_content( refresh= True) # returns new value get_content( ) # after, refresh, it returns the new value
1) secret.
2) secret.
3) secret.
4) secret.
Here: https:/ /pastebin. ubuntu. com/p/Fbp88TDSS P/
The "operator-password" gets updated.
Also, I have ran the same change (i.e. "set-password" action) multiple times successfully now. That means the charm can also recover the up-to-date secret once secret-changed event is over.
I have proposed a PR with the fix: https:/ /github. com/juju/ juju/pull/ 16316