diff --git a/README.md b/README.md index 9825e44..0665bc0 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,11 @@ To obtain the CA certificate from this charm, your charm needs to support the ```console juju relate self-signed-certificates:send-ca-cert ``` +To get the CA certificate run: + +```console +juju run self-signed-certificates/0 get-ca-certificate +``` ## Get the certificates issued by the charm diff --git a/actions.yaml b/actions.yaml index d7e1842..d05350d 100644 --- a/actions.yaml +++ b/actions.yaml @@ -1,2 +1,6 @@ +get-ca-certificate: + description: Outputs the CA cert. + get-issued-certificates: description: Outputs the certificates issued by the charm. + diff --git a/src/charm.py b/src/charm.py index 9aa5d96..4073fb0 100755 --- a/src/charm.py +++ b/src/charm.py @@ -44,6 +44,7 @@ def __init__(self, *args): self._on_certificate_creation_request, ) self.framework.observe(self.on.secret_expired, self._configure_ca) + self.framework.observe(self.on.get_ca_certificate_action, self._on_get_ca_certificate) self.framework.observe( self.on.get_issued_certificates_action, self._on_get_issued_certificates ) @@ -184,7 +185,7 @@ def _on_certificate_creation_request(self, event: CertificateCreationRequestEven """Handler for certificate requests. Args: - event (CertificateCreationRequestEvent): Jujue event + event (CertificateCreationRequestEvent): Juju event """ if not self.unit.is_leader(): return @@ -195,7 +196,7 @@ def _on_certificate_creation_request(self, event: CertificateCreationRequestEven event.defer() return if not self._root_certificate_is_stored: - self.unit.status = WaitingStatus("Root Certificates is not yet generated") + self.unit.status = WaitingStatus("Root Certificate is not yet generated") event.defer() return ca_certificate_secret = self.model.get_secret(label=CA_CERTIFICATES_SECRET_LABEL) @@ -216,6 +217,19 @@ def _on_certificate_creation_request(self, event: CertificateCreationRequestEven ) logger.info(f"Generated certificate for relation {event.relation_id}") + def _on_get_ca_certificate(self, event: ActionEvent): + """Handler for the get-ca-certificate action. + + Args: + event (ActionEvent): Juju event + """ + if not self._root_certificate_is_stored: + event.fail("Root Certificate is not yet generated") + return + ca_certificate_secret = self.model.get_secret(label=CA_CERTIFICATES_SECRET_LABEL) + ca_certificate_secret_content = ca_certificate_secret.get_content() + event.set_results({"ca-certificate": ca_certificate_secret_content["ca-certificate"]}) + def _on_send_ca_cert_relation_joined(self, event: RelationJoinedEvent): self._send_ca_cert(rel_id=event.relation.id) diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py index bce4627..7678820 100644 --- a/tests/unit/test_charm.py +++ b/tests/unit/test_charm.py @@ -172,7 +172,7 @@ def test_given_root_certificate_not_yet_generated_when_certificate_request_then_ self.assertEqual( self.harness.model.unit.status, - WaitingStatus("Root Certificates is not yet generated"), + WaitingStatus("Root Certificate is not yet generated"), ) @patch(f"{TLS_LIB_PATH}.TLSCertificatesProvidesV2.set_relation_certificate") @@ -290,3 +290,32 @@ def test_given_certificates_issued_when_get_issued_certificates_action_then_acti } action_event.set_results.assert_called_with(expected_certificates) + + def test_given_ca_cert_generated_when_get_ca_certificate_action_then_returns_ca_certificate( + self, + ): + self.harness.set_leader(is_leader=True) + ca_certificate = "whatever CA certificate" + + self.harness._backend.secret_add( + label="ca-certificates", + content={ + "ca-certificate": ca_certificate, + "private-key": "whatever private key", + "private-key-password": "whatever private_key_password", + }, + ) + + action_event = Mock() + self.harness.charm._on_get_ca_certificate(action_event) + expected_certificate = { + "ca-certificate": ca_certificate, + } + + action_event.set_results.assert_called_with(expected_certificate) + + def test_given_ca_cert_not_generated_when_get_ca_certificate_action_then_action_fails(self): + self.harness.set_leader(is_leader=True) + action_event = Mock() + self.harness.charm._on_get_ca_certificate(action_event) + action_event.fail.assert_called_with("Root Certificate is not yet generated")