Merge "Update relation data from configure_charm" into main
This commit is contained in:
commit
f24edf6a06
ops-sunbeam/ops_sunbeam
@ -236,6 +236,14 @@ class OSBaseOperatorCharm(ops.charm.CharmBase):
|
||||
"Not all relations are ready"
|
||||
)
|
||||
|
||||
def update_relations(self):
|
||||
"""Update relation data."""
|
||||
for handler in self.relation_handlers:
|
||||
try:
|
||||
handler.update_relation_data()
|
||||
except NotImplementedError:
|
||||
logging.debug(f"send_requests not implemented for {handler}")
|
||||
|
||||
def configure_unit(self, event: ops.framework.EventBase) -> None:
|
||||
"""Run configuration on this unit."""
|
||||
self.check_leader_ready()
|
||||
@ -270,6 +278,11 @@ class OSBaseOperatorCharm(ops.charm.CharmBase):
|
||||
def configure_charm(self, event: ops.framework.EventBase) -> None:
|
||||
"""Catchall handler to configure charm services."""
|
||||
with sunbeam_guard.guard(self, "Bootstrapping"):
|
||||
# Publishing relation data may be dependent on something else (like
|
||||
# receiving a piece of data from the leader). To cover that
|
||||
# republish relation if the relation adapter has implemented an
|
||||
# update method.
|
||||
self.update_relations()
|
||||
self.configure_unit(event)
|
||||
self.configure_app(event)
|
||||
self.bootstrap_status.set(ActiveStatus())
|
||||
|
@ -138,6 +138,10 @@ class RelationHandler(ops.charm.Object):
|
||||
"""Pull together context for rendering templates."""
|
||||
return self.interface_properties()
|
||||
|
||||
def update_relation_data(self):
|
||||
"""Update relation outside of relation context."""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class IngressHandler(RelationHandler):
|
||||
"""Base class to handle Ingress relations."""
|
||||
@ -826,6 +830,7 @@ class TlsCertificatesHandler(RelationHandler):
|
||||
) -> None:
|
||||
"""Run constructor."""
|
||||
self.sans = sans
|
||||
self._private_key = None
|
||||
super().__init__(charm, relation_name, callback_f, mandatory)
|
||||
try:
|
||||
self.store = self.PeerKeyStore(
|
||||
@ -833,6 +838,7 @@ class TlsCertificatesHandler(RelationHandler):
|
||||
)
|
||||
except KeyError:
|
||||
self.store = self.LocalDBKeyStore(charm._state)
|
||||
self.setup_private_key()
|
||||
|
||||
def setup_event_handler(self) -> None:
|
||||
"""Configure event handlers for tls relation."""
|
||||
@ -846,7 +852,6 @@ class TlsCertificatesHandler(RelationHandler):
|
||||
self.certificates = TLSCertificatesRequiresV1(
|
||||
self.charm, "certificates"
|
||||
)
|
||||
self.framework.observe(self.charm.on.install, self._on_install)
|
||||
self.framework.observe(
|
||||
self.charm.on.certificates_relation_joined,
|
||||
self._on_certificates_relation_joined,
|
||||
@ -869,7 +874,8 @@ class TlsCertificatesHandler(RelationHandler):
|
||||
)
|
||||
return self.certificates
|
||||
|
||||
def _on_install(self, event: ops.framework.EventBase) -> None:
|
||||
def setup_private_key(self) -> None:
|
||||
"""Create and store private key if needed."""
|
||||
# Lazy import to ensure this lib is only required if the charm
|
||||
# has this relation.
|
||||
from charms.tls_certificates_interface.v1.tls_certificates import (
|
||||
@ -877,45 +883,65 @@ class TlsCertificatesHandler(RelationHandler):
|
||||
)
|
||||
|
||||
if not self.store.store_ready():
|
||||
event.defer()
|
||||
logger.debug("Store not ready, cannot generate key")
|
||||
return
|
||||
|
||||
if self.store.get_private_key():
|
||||
# Secret already saved
|
||||
logger.debug("Private key already present")
|
||||
self._private_key = self.store.get_private_key()
|
||||
private_key_secret_id = self.store.get_private_key()
|
||||
private_key_secret = self.model.get_secret(
|
||||
id=private_key_secret_id
|
||||
)
|
||||
self._private_key = private_key_secret.get_content().get(
|
||||
"private-key"
|
||||
)
|
||||
return
|
||||
|
||||
private_key = generate_private_key()
|
||||
self._private_key = generate_private_key()
|
||||
private_key_secret = self.model.unit.add_secret(
|
||||
{"private-key": private_key.decode()},
|
||||
{"private-key": self._private_key.decode()},
|
||||
label=f"{self.charm.model.unit}-private-key",
|
||||
)
|
||||
|
||||
self.store.set_private_key(private_key_secret.id)
|
||||
|
||||
@property
|
||||
def private_key(self):
|
||||
"""Private key for certificates."""
|
||||
logger.debug("Returning private key: {}".format(self._private_key))
|
||||
return self._private_key
|
||||
|
||||
def update_relation_data(self):
|
||||
"""Request certificates outside of relation context."""
|
||||
self._request_certificates()
|
||||
|
||||
def _on_certificates_relation_joined(
|
||||
self, event: ops.framework.EventBase
|
||||
) -> None:
|
||||
"""Request certificates in response to relation join event."""
|
||||
self._request_certificates()
|
||||
|
||||
def _request_certificates(self):
|
||||
"""Request certificates from remote provider."""
|
||||
# Lazy import to ensure this lib is only required if the charm
|
||||
# has this relation.
|
||||
from charms.tls_certificates_interface.v1.tls_certificates import (
|
||||
generate_csr,
|
||||
)
|
||||
|
||||
if not self.store.store_ready():
|
||||
event.defer()
|
||||
if self.ready:
|
||||
logger.debug("Certificate request already complete.")
|
||||
return
|
||||
|
||||
private_key = None
|
||||
private_key_secret_id = self.store.get_private_key()
|
||||
|
||||
if private_key_secret_id:
|
||||
private_key_secret = self.model.get_secret(
|
||||
id=private_key_secret_id
|
||||
)
|
||||
private_key = private_key_secret.get_content().get("private-key")
|
||||
if self.private_key:
|
||||
logger.debug("Private key found, requesting certificates")
|
||||
else:
|
||||
logger.debug("Cannot request certificates, private key not found")
|
||||
return
|
||||
|
||||
csr = generate_csr(
|
||||
private_key=private_key.encode(),
|
||||
private_key=self.private_key.encode(),
|
||||
subject=self.charm.model.unit.name.replace("/", "-"),
|
||||
sans=self.sans,
|
||||
)
|
||||
@ -998,16 +1024,8 @@ class TlsCertificatesHandler(RelationHandler):
|
||||
cert = certs["cert"]
|
||||
ca_cert = certs["ca"] + "\n" + "\n".join(certs["chain"])
|
||||
|
||||
key = None
|
||||
private_key_secret_id = self.store.get_private_key()
|
||||
if private_key_secret_id:
|
||||
private_key_secret = self.model.get_secret(
|
||||
id=private_key_secret_id
|
||||
)
|
||||
key = private_key_secret.get_content().get("private-key")
|
||||
|
||||
ctxt = {
|
||||
"key": key,
|
||||
"key": self.private_key,
|
||||
"cert": cert,
|
||||
"ca_cert": ca_cert,
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user