From 4169cf178af897d86afff2fd4073fa8060111d1c Mon Sep 17 00:00:00 2001 From: Leon <82407168+sed-i@users.noreply.github.com> Date: Wed, 27 Mar 2024 14:33:09 -0400 Subject: [PATCH] Fix cert chain handling (#83) * Add backwards compat for chain * Also apply to v1 --- lib/charms/observability_libs/v0/cert_handler.py | 12 ++++++++++-- lib/charms/observability_libs/v1/cert_handler.py | 11 +++++------ tests/integration/conftest.py | 2 +- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/charms/observability_libs/v0/cert_handler.py b/lib/charms/observability_libs/v0/cert_handler.py index 07d9063..9dcfc8f 100644 --- a/lib/charms/observability_libs/v0/cert_handler.py +++ b/lib/charms/observability_libs/v0/cert_handler.py @@ -67,7 +67,7 @@ LIBID = "b5cd5cd580f3428fa5f59a8876dcbe6a" LIBAPI = 0 -LIBPATCH = 10 +LIBPATCH = 11 def is_ip_address(value: str) -> bool: @@ -378,7 +378,15 @@ def _server_cert(self, value: str): def _chain(self) -> str: if self._peer_relation: if chain := self._peer_relation.data[self.charm.unit].get("chain", ""): - return json.loads(cast(str, chain)) + chain = json.loads(chain) + + # In a previous version of this lib, chain used to be a list. + # Convert the List[str] to str, per + # https://github.com/canonical/tls-certificates-interface/pull/141 + if isinstance(chain, list): + chain = "\n\n".join(reversed(chain)) + + return cast(str, chain) return "" @_chain.setter diff --git a/lib/charms/observability_libs/v1/cert_handler.py b/lib/charms/observability_libs/v1/cert_handler.py index 4c43fe4..1375550 100644 --- a/lib/charms/observability_libs/v1/cert_handler.py +++ b/lib/charms/observability_libs/v1/cert_handler.py @@ -32,18 +32,17 @@ Since this library uses [Juju Secrets](https://juju.is/docs/juju/secret) it requires Juju >= 3.0.3. """ import ipaddress -import json import socket from itertools import filterfalse from typing import List, Optional, Union try: - from charms.tls_certificates_interface.v2.tls_certificates import ( # type: ignore + from charms.tls_certificates_interface.v3.tls_certificates import ( # type: ignore AllCertificatesInvalidatedEvent, CertificateAvailableEvent, CertificateExpiringEvent, CertificateInvalidatedEvent, - TLSCertificatesRequiresV2, + TLSCertificatesRequiresV3, generate_csr, generate_private_key, ) @@ -66,7 +65,7 @@ LIBID = "b5cd5cd580f3428fa5f59a8876dcbe6a" LIBAPI = 1 -LIBPATCH = 3 +LIBPATCH = 4 def is_ip_address(value: str) -> bool: @@ -128,7 +127,7 @@ def __init__( self.sans_dns = list(filterfalse(is_ip_address, sans)) self.certificates_relation_name = certificates_relation_name - self.certificates = TLSCertificatesRequiresV2(self.charm, self.certificates_relation_name) + self.certificates = TLSCertificatesRequiresV3(self.charm, self.certificates_relation_name) self.framework.observe( self.charm.on.config_changed, @@ -278,7 +277,7 @@ def _on_certificate_available(self, event: CertificateAvailableEvent) -> None: content = { "ca-cert": event.ca, "server-cert": event.certificate, - "chain": json.dumps(event.chain), + "chain": event.chain_as_pem(), "csr": event_csr, } try: diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 8426fb5..ad5470d 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -79,7 +79,7 @@ async def tester_charm(ops_test: OpsTest) -> Path: fetch_tls_cmd = [ "charmcraft", "fetch-lib", - "charms.tls_certificates_interface.v2.tls_certificates", + "charms.tls_certificates_interface.v3.tls_certificates", ] await ops_test.run(*fetch_tls_cmd) shutil.move("lib/charms/tls_certificates_interface", f"{TESTINGCHARM_PATH}/lib/charms/")