-
Notifications
You must be signed in to change notification settings - Fork 129
Description
It is possible to create a relation Object for a relation that does not exist, as long as the relation ID exists,
Given a charm with a relation integrated, with id 1, I can run this:
relation = self.model.get_relation("not-integrated", 1)
relation.data[self.app]Interestingly:
- The relation object creation is not blocked
- accessing the relation databag returns the databag of the relation with id 1.
The reason for the first part is here
We provide both the relation name and the relation id. We fall in the else case here and return a relation object.
The thing is: we're not providing the information for a dead relation, AND we do have a relation existing with that id to a different relation name.
I think this case should raise an error. It's not that the relation is dead but we refuse to forget it.
Maybe the loop a few lines above should also check if there isn't a relation that has this relation ID.
This would work as relation ids are unique throughout a model lifetime.
The reason for the second part is this line: while the relation object is created with a relation name and a relation id, loading the databag is ultimately done using only the relation id.
The reason: we pass a relation with an invalid name BUT a valid relation id. And when building the RelationDataContent object it uses only the relation ID. And that relation id is valid and does exist and hence we're accessing its databag.
The easy way to go would be to craft a valid identifier when running the relation-get hook command: it accepts relation-get -r <relation_id> but also relation-get -r <relation_name>:<relation_id>.
This would ensure that we're accessing exactly what is needed instead of returning data for a non existing relation.