Closed DnPlas closed 2 months ago
Extra information:
According to get_secret
docs, it only raises SecretNotFoundError
if the secret does not exist, but _ModelBackend.secret_get
, which is called by the model.get_secret()
method, will raise a ModelError under other conditions, which can include the permission denied scenario that I am describing.
@IronCore864 @tonyandrewmeyer It makes sense to me to make the testing exception the same as the real one. So I think we just change the SecretNotFoundError
here to ModelError
. Sound reasonable?
@IronCore864 @tonyandrewmeyer It makes sense to me to make the testing exception the same as the real one.
I do agree with this in general.
So I think we just change the
SecretNotFoundError
here toModelError
. Sound reasonable?
However, I don't think this is the right fix here. I think this is a Juju bug. All of the other permission errors (like trying to do a get_info()
when only having view permission, or trying to get a charm secret that you haven't been granted permission to) raise SecretNotFoundError
). Apart from the inconsistency, behaving differently when there is a secret with no access and when there is no secret feels leaky to me.
So, in my opinion, we should open a Juju bug instead.
So, in my opinion, we should open a Juju bug instead.
Checked with the Juju team and they agree that it should be consistent in Juju, so I opened a Juju bug.
According to
get_secret
docs, it only raisesSecretNotFoundError
if the secret does not exist
Opened #1231 to make this explicit in the docs.
Actually, I got this wrong. Charm secrets do return "permission denied" as well as user ones, so there must be an ops issue here.
Juju 3.4.2, Microk8s, I get this behaviour:
hook tool | issue | user secret | charm secret |
---|---|---|---|
secret-get | no permission | "permission denied" | "permission denied" |
secret-info-get | no permission | "not found" | "not found" |
secret-set | no permission | delayed permission denied | delayed permission denied |
secret-remove | no permission | delayed permission denied | delayed permission denied |
secret-grant | no permission | "not found" | "not found" |
secret-revoke | no permission | delayed permission denied | delayed permission denied |
secret-get | doesn't exist | "not found" | "not found" |
secret-info-get | doesn't exist | "not found" | "not found" |
secret-set | doesn't exist | delayed not found | delayed not found |
secret-remove | doesn't exist | delayed not found | delayed not found |
secret-grant | doesn't exist | "not found" | "not found" |
secret-revoke | doesn't exist | delayed not found | delayed not found |
For the "delayed" cases, the hook tool returns successfully, and then when the hook finishes (after ops is done) the charm goes into error state with something like this in the debug-log:
unit-dummycharm-1: 12:56:16 ERROR juju.worker.uniter.context cannot apply changes: removing secrets: permission denied
unit-dummycharm-1: 12:56:16 ERROR juju.worker.uniter.operation hook "config-changed" (via hook dispatching script: dispatch) failed: removing secrets: permission denied
Also discussing this with @barrettj12 who is working on the Juju ticket.
1176 introduced support for user secrets in Harness, but it looks like it is not modelling the actual Juju behaviour when a user secret hasn't been granted to a charm and it tries to get a secret with
self.model.get_secret(id=<id-from-config>)
.On an actual model, if the charm config gets updated with a secret ID, but the charm hasn't been granted access to the secret,
ops.model.ModelError: ERROR permission denied
will be raised, but it seems that when testing, harness makes the charm to raise a different exceptionops.model.SecretNotFoundError: Secret 'secret:16320250-1b76-4552-94d9-10ff484f88cb' not granted access to 'istio-pilot
when calling the exact same piece of code.Steps to reproduce
juju config <charm-name> my-secret=secret:some-id
ModelError
but aSecretNotFoundError
exception is raised instead: