-
Notifications
You must be signed in to change notification settings - Fork 13
Description
Enhancement Proposal
The current implementation of TLS certificates interface does not allow to set the private key dynamically, while it can be needed.
A scenario that I have in mind is the following:
* private key is stored in a juju model secret
* Secret is granted to the application
* juju config <my-app> tls-private-key=<secret-id>
On config changed, I want to validate the private key and refresh certificates if it's valid. If it's not valid, I want to continue using the former value of the private key that was used, no matter if it is the autogenerated one OR one former private key that was used by the charm.
In that situation, I have two possibilities:
private_key: PrivateKey | None = get_and_validate(self.charm.config.get("tls-private-key")
self.requirer = TLSCertificatesRequiresV4(
charm=self.charm,
...
private_key=private_key
)OR
private_key: PrivateKey | None = get_and_validate(self.charm.get_secret(<my-local-secret>))
self.requirer = TLSCertificatesRequiresV4(
charm=self.charm,
...
private_key=private_key
)In the first scenario, if I had configured a valid key and then I update my config to a new invalid key, all certificate refreshes will lead to generating a new private key, which is not what is expected in production settings, we would expect to keep the formerly configured private key. So this does not work as is.
In the second scenario, assuming I provide a valid key, I want to be able to emit the certificate refresh event to generate immediately new certificates with the new key. However, as I don't have a way to set the new private key, the refresh event will be using the former private key as it is defined statically at the beginning of the juju hook.
What I want to be able to do is
refresh_tls_certificates_event = EventSource(...)
private_key: PrivateKey | None = get_and_validate(self.charm.get_secret(<my-local-secret>))
self.requirer = TLSCertificatesRequiresV4(
charm=self.charm,
...
private_key=private_key,
refresh_events=[self.refresh_tls_certificates_event]
)
def _on_config_changed(self, event):
private_key : PrivateKey | None = get_and_validate(self.charm.config.get("tls-private-key"))
if private_key:
self.charm.set_secret(<my-local-secret>, value=private_key.raw)
self.requirer.private_key = private_key
self.refresh_tls_certificates_event.emit() # This will refresh with the new keyOne way of doing this would be to provide a setter to the private_key property so that I can set this to the value I get.
@private_key.setter
def private_key(self, value: PrivateKey | None):
if not value:
return
self._private_key = value