Skip to content

Commit

Permalink
Bumps libraries versions
Browse files Browse the repository at this point in the history
  • Loading branch information
gruyaume committed Oct 31, 2023
1 parent 9b92082 commit 5f5ab2e
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def _on_certificates_relation_joined(self, event: RelationJoinedEvent):
certificate = "my certificate"
ca = "my CA certificate"
chain = ["certificate 1", "certificate 2"]
self.certificate_transfer.set_certificate(certificate=certificate, ca=ca, chain=chain)
self.certificate_transfer.set_certificate(certificate=certificate, ca=ca, chain=chain, relation_id=event.relation.id)
if __name__ == "__main__":
Expand All @@ -54,6 +54,7 @@ def _on_certificates_relation_joined(self, event: RelationJoinedEvent):
from lib.charms.certificate_transfer_interface.v0.certificate_transfer import (
CertificateAvailableEvent,
CertificateRemovedEvent,
CertificateTransferRequires,
)
Expand All @@ -65,11 +66,18 @@ def __init__(self, *args):
self.framework.observe(
self.certificate_transfer.on.certificate_available, self._on_certificate_available
)
self.framework.observe(
self.certificate_transfer.on.certificate_removed, self._on_certificate_removed
)
def _on_certificate_available(self, event: CertificateAvailableEvent):
print(event.certificate)
print(event.ca)
print(event.chain)
print(event.relation_id)
def _on_certificate_removed(self, event: CertificateRemovedEvent):
print(event.relation_id)
if __name__ == "__main__":
Expand All @@ -87,10 +95,10 @@ def _on_certificate_available(self, event: CertificateAvailableEvent):

import json
import logging
from typing import List, Optional
from typing import List

from jsonschema import exceptions, validate # type: ignore[import]
from ops.charm import CharmBase, CharmEvents, RelationChangedEvent
from jsonschema import exceptions, validate # type: ignore[import-untyped]
from ops.charm import CharmBase, CharmEvents, RelationBrokenEvent, RelationChangedEvent
from ops.framework import EventBase, EventSource, Handle, Object

# The unique Charmhub library identifier, never change it
Expand All @@ -101,7 +109,7 @@ def _on_certificate_available(self, event: CertificateAvailableEvent):

# Increment this PATCH version before using `charmcraft publish-lib` or reset
# to 0 if you are raising the major API version
LIBPATCH = 1
LIBPATCH = 5

PYDEPS = ["jsonschema"]

Expand Down Expand Up @@ -161,25 +169,45 @@ def __init__(
certificate: str,
ca: str,
chain: List[str],
relation_id: int,
):
super().__init__(handle)
self.certificate = certificate
self.ca = ca
self.chain = chain
self.relation_id = relation_id

def snapshot(self) -> dict:
"""Return snapshot."""
return {
"certificate": self.certificate,
"ca": self.ca,
"chain": self.chain,
"relation_id": self.relation_id,
}

def restore(self, snapshot: dict):
"""Restores snapshot."""
self.certificate = snapshot["certificate"]
self.ca = snapshot["ca"]
self.chain = snapshot["chain"]
self.relation_id = snapshot["relation_id"]


class CertificateRemovedEvent(EventBase):
"""Charm Event triggered when a TLS certificate is removed."""

def __init__(self, handle: Handle, relation_id: int):
super().__init__(handle)
self.relation_id = relation_id

def snapshot(self) -> dict:
"""Return snapshot."""
return {"relation_id": self.relation_id}

def restore(self, snapshot: dict):
"""Restores snapshot."""
self.relation_id = snapshot["relation_id"]


def _load_relation_data(raw_relation_data: dict) -> dict:
Expand All @@ -204,6 +232,7 @@ class CertificateTransferRequirerCharmEvents(CharmEvents):
"""List of events that the Certificate Transfer requirer charm can leverage."""

certificate_available = EventSource(CertificateAvailableEvent)
certificate_removed = EventSource(CertificateRemovedEvent)


class CertificateTransferProvides(Object):
Expand All @@ -219,7 +248,7 @@ def set_certificate(
certificate: str,
ca: str,
chain: List[str],
relation_id: Optional[int] = None,
relation_id: int,
) -> None:
"""Add certificates to relation data.
Expand All @@ -245,7 +274,7 @@ def set_certificate(
relation.data[self.model.unit]["ca"] = ca
relation.data[self.model.unit]["chain"] = json.dumps(chain)

def remove_certificate(self, relation_id: Optional[int] = None) -> None:
def remove_certificate(self, relation_id: int) -> None:
"""Remove a given certificate from relation data.
Args:
Expand Down Expand Up @@ -303,6 +332,9 @@ def __init__(
self.framework.observe(
charm.on[relationship_name].relation_changed, self._on_relation_changed
)
self.framework.observe(
charm.on[relationship_name].relation_broken, self._on_relation_broken
)

@staticmethod
def _relation_data_is_valid(relation_data: dict) -> bool:
Expand Down Expand Up @@ -343,4 +375,16 @@ def _on_relation_changed(self, event: RelationChangedEvent) -> None:
certificate=remote_unit_relation_data.get("certificate"),
ca=remote_unit_relation_data.get("ca"),
chain=remote_unit_relation_data.get("chain"),
relation_id=event.relation.id,
)

def _on_relation_broken(self, event: RelationBrokenEvent) -> None:
"""Handler triggered on relation broken event.
Args:
event: Juju event
Returns:
None
"""
self.on.certificate_removed.emit(relation_id=event.relation.id)
39 changes: 25 additions & 14 deletions lib/charms/tls_certificates_interface/v2/tls_certificates.py
Original file line number Diff line number Diff line change
Expand Up @@ -1208,18 +1208,18 @@ def _on_relation_changed(self, event: RelationChangedEvent) -> None:
for certificate_creation_request in provider_certificates
]
requirer_unit_certificate_requests = [
(
certificate_creation_request["certificate_signing_request"],
certificate_creation_request.get("ca", False),
)
{
"csr": certificate_creation_request["certificate_signing_request"],
"is_ca": certificate_creation_request.get("ca", False),
}
for certificate_creation_request in requirer_csrs
]
for certificate_request in requirer_unit_certificate_requests:
if certificate_request[0] not in provider_csrs:
if certificate_request["csr"] not in provider_csrs:
self.on.certificate_creation_request.emit(
certificate_signing_request=certificate_request[0],
certificate_signing_request=certificate_request["csr"],
relation_id=event.relation.id,
is_ca=certificate_request[1],
is_ca=certificate_request["is_ca"],
)
self._revoke_certificates_for_which_no_csr_exists(relation_id=event.relation.id)

Expand Down Expand Up @@ -1377,8 +1377,17 @@ def __init__(
self.framework.observe(charm.on.update_status, self._on_update_status)

@property
def _requirer_csrs(self) -> List[Dict[str, Any]]:
"""Returns list of requirer's CSRs from relation data."""
def _requirer_csrs(self) -> List[Dict[str, Union[bool, str]]]:
"""Returns list of requirer's CSRs from relation data.
Example:
[
{
"certificate_signing_request": "-----BEGIN CERTIFICATE REQUEST-----...",
"ca": false
}
]
"""
relation = self.model.get_relation(self.relationship_name)
if not relation:
raise RuntimeError(f"Relation {self.relationship_name} does not exist")
Expand Down Expand Up @@ -1406,6 +1415,7 @@ def _add_requirer_csr(self, csr: str, is_ca: bool) -> None:
Args:
csr (str): Certificate Signing Request
is_ca (bool): Whether the certificate is a CA certificate
Returns:
None
Expand All @@ -1416,7 +1426,7 @@ def _add_requirer_csr(self, csr: str, is_ca: bool) -> None:
f"Relation {self.relationship_name} does not exist - "
f"The certificate request can't be completed"
)
new_csr_dict = {
new_csr_dict: Dict[str, Union[bool, str]] = {
"certificate_signing_request": csr,
"ca": is_ca,
}
Expand All @@ -1443,11 +1453,12 @@ def _remove_requirer_csr(self, csr: str) -> None:
f"The certificate request can't be completed"
)
requirer_csrs = copy.deepcopy(self._requirer_csrs)
csr_dict = {"certificate_signing_request": csr}
if csr_dict not in requirer_csrs:
logger.info("CSR not in relation data - Doing nothing")
if not requirer_csrs:
logger.info("No CSRs in relation data - Doing nothing")
return
requirer_csrs.remove(csr_dict)
for requirer_csr in requirer_csrs:
if requirer_csr["certificate_signing_request"] == csr:
requirer_csrs.remove(requirer_csr)
relation.data[self.model.unit]["certificate_signing_requests"] = json.dumps(requirer_csrs)

def request_certificate_creation(
Expand Down

0 comments on commit 5f5ab2e

Please sign in to comment.